Updated on 2026-08-14
This commit is contained in:
commit
364ef1e165
205 changed files with 17463 additions and 627 deletions
|
|
@ -3,6 +3,7 @@ apply plugin: 'kotlin-android'
|
|||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
apply plugin: 'com.google.firebase.firebase-perf'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
|
||||
static def generateVersionName() {
|
||||
|
|
@ -72,6 +73,7 @@ repositories {
|
|||
}
|
||||
configurations {
|
||||
all*.exclude group: 'com.google.guava', module: 'listenablefuture'
|
||||
implementation.exclude module:'protobuf-lite'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
@ -79,22 +81,22 @@ dependencies {
|
|||
implementation project(':tangem-sdk-old')
|
||||
implementation project(':server-android')
|
||||
|
||||
implementation 'androidx.navigation:navigation-fragment:2.1.0'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
|
||||
implementation 'androidx.navigation:navigation-fragment:2.2.2'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.2.2'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:2.1.0"
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:2.1.0"
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.fragment:fragment:1.1.0'
|
||||
implementation 'androidx.fragment:fragment:1.2.4'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation "androidx.preference:preference:1.1.0"
|
||||
implementation 'androidx.biometric:biometric:1.0.0-beta01'
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
implementation 'com.google.android.material:material:1.1.0-beta01'
|
||||
implementation "androidx.preference:preference:1.1.1"
|
||||
implementation 'androidx.biometric:biometric:1.0.1'
|
||||
implementation 'androidx.core:core-ktx:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
|
||||
implementation 'com.google.dagger:dagger:2.21'
|
||||
implementation 'com.google.dagger:dagger:2.24'
|
||||
kapt 'com.google.dagger:dagger-compiler:2.21'
|
||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.21'
|
||||
implementation 'com.google.zxing:core:3.4.0'
|
||||
|
|
@ -113,8 +115,8 @@ dependencies {
|
|||
implementation "com.orhanobut:hawk:2.0.1"
|
||||
implementation 'co.nstant.in:cbor:0.8'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$versions.kotlin"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.2'
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.2"
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3"
|
||||
// implementation 'org.bitcoinj:bitcoinj-parent:0.14.7' //TODO: is this needed?
|
||||
implementation 'org.bitcoinj:bitcoinj-core:0.15.2'
|
||||
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||
|
|
@ -126,8 +128,9 @@ dependencies {
|
|||
// implementation 'com.github.stellar:java-stellar-sdk:0.4.1'
|
||||
implementation 'net.i2p.crypto:eddsa:0.3.0'
|
||||
|
||||
implementation 'com.google.firebase:firebase-analytics:17.2.3'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta02'
|
||||
implementation 'com.google.firebase:firebase-analytics:17.3.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:17.0.0-beta04'
|
||||
implementation 'com.google.firebase:firebase-perf:19.0.6'
|
||||
|
||||
implementation files('libs/ripple-core-0.0.1.jar')
|
||||
//4 dependencies for ripple-core TODO: move to module?
|
||||
|
|
@ -158,4 +161,7 @@ dependencies {
|
|||
//dependencies for flow demo
|
||||
implementation 'io.grpc:grpc-okhttp:1.28.0'
|
||||
implementation 'io.grpc:grpc-stub:1.28.0'
|
||||
|
||||
//dependencies for TokenEmvEngine
|
||||
implementation 'com.github.walleth.kethereum:extensions_kotlin:0.81.4'
|
||||
}
|
||||
|
|
@ -2,8 +2,6 @@ package com.tangem
|
|||
|
||||
import android.app.Application
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.tangem.data.dp.PrefsManager
|
||||
|
|
@ -80,10 +78,7 @@ class App : Application() {
|
|||
)
|
||||
}
|
||||
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(Analytics.isEnabled())
|
||||
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(
|
||||
Analytics.isEnabled() && !BuildConfig.DEBUG
|
||||
)
|
||||
Analytics.setFirebaseEnabled(this)
|
||||
}
|
||||
|
||||
private fun buildToastHelperComponent(): ToastHelperComponent {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ public enum Blockchain {
|
|||
Eos("EOS", "EOS", 10000.0, R.drawable.tangem2, "EOS"),
|
||||
Ducatus("DUC", "DUC", 100000000.0, R.drawable.tangem2, "Ducatus"),
|
||||
Tezos("TEZOS", "XTZ", 10000000.0, R.drawable.ic_logo_tezos, "Tezos"),
|
||||
FlowDemo("FLOW/demo", "", 1.0, R.drawable.tangem2, "Flow demo");
|
||||
FlowDemo("FLOW/demo", "", 1.0, R.drawable.tangem2, "Flow demo"),
|
||||
TokenEmv("TTW", "ETH", 1.0, R.drawable.ic_logo_ethereum, "Ethereum");
|
||||
|
||||
Blockchain(String ID, String currency, double multiplier, int imageResource, String officialName) {
|
||||
mID = ID;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,14 @@ public class Server {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ApiInfuraRopsten {
|
||||
public static final String URL_INFURA_ROPSTEN = ServerURL.API_INFURA_ROPSTEN;
|
||||
|
||||
public static class Method {
|
||||
public static final String MAIN = "v3/613a0b14833145968b1f656240c7d245";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class ApiSoChain {
|
||||
public static final String URL = ServerURL.API_SOCHAIN_V2;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ public class ServerApiInfura {
|
|||
public ServerApiInfura(Blockchain blockchain) {
|
||||
if (blockchain == Blockchain.EthereumTestNet) {
|
||||
infuraApi = App.Companion.getNetworkComponent().getRetrofitInfuraTestnet().create(InfuraApi.class);
|
||||
} else if (blockchain == Blockchain.TokenEmv) {
|
||||
infuraApi = App.Companion.getNetworkComponent().getRetrofitInfuraRopsten().create(InfuraApi.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
package com.tangem.data.network
|
||||
|
||||
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
|
||||
import com.tangem.data.network.model.TokenEmvGetTransferFeeAnswer
|
||||
import com.tangem.data.network.model.TokenEmvGetTransferFeeBody
|
||||
import com.tangem.data.network.model.TokenEmvTransferAnswer
|
||||
import com.tangem.data.network.model.TokenEmvTransferBody
|
||||
import com.tangem.tangem_card.util.Log
|
||||
import io.reactivex.SingleObserver
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.gson.GsonConverterFactory
|
||||
import retrofit2.converter.scalars.ScalarsConverterFactory
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class ServerApiTokenEmv {
|
||||
private val TAG = ServerApiTokenEmv::class.java.simpleName
|
||||
|
||||
private val tangemServer = "https://emvsupport.appspot.com/"
|
||||
|
||||
private val tokenEmvApi = Retrofit.Builder()
|
||||
.baseUrl(tangemServer)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.addConverterFactory(ScalarsConverterFactory.create())
|
||||
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //logging for testing
|
||||
.client(OkHttpClient.Builder().addInterceptor(
|
||||
HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
|
||||
).build())
|
||||
.build()
|
||||
.create(TokenEmvApi::class.java)
|
||||
|
||||
fun transfer(tokenEmvTransferBody: TokenEmvTransferBody, transferObserver: SingleObserver<TokenEmvTransferAnswer>) {
|
||||
Log.i(TAG, "new transfer request")
|
||||
|
||||
tokenEmvApi.transfer(tokenEmvTransferBody)
|
||||
.timeout(30, TimeUnit.SECONDS)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(transferObserver)
|
||||
}
|
||||
|
||||
fun getTransferFee(tokenEmvGetTransferFeeBody: TokenEmvGetTransferFeeBody, transferObserver: SingleObserver<TokenEmvGetTransferFeeAnswer>) {
|
||||
Log.i(TAG, "new get transfer fee request")
|
||||
|
||||
tokenEmvApi.getTransferFee(tokenEmvGetTransferFeeBody)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(transferObserver)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ class ServerURL {
|
|||
static final String API_COINMARKETCAP = "https://pro-api.coinmarketcap.com/";
|
||||
static final String API_INFURA = "https://mainnet.infura.io/";
|
||||
static final String API_INFURA_TESTNET = "https://rinkeby.infura.io/";
|
||||
static final String API_INFURA_ROPSTEN = "https://ropsten.infura.io/";
|
||||
static final String API_SOCHAIN_V2 = "https://chain.so/";
|
||||
static final String API_ESTIMATEFEE = "https://estimatefee.com/";
|
||||
static final String API_UPDATE_VERSION = "https://raw.githubusercontent.com/";
|
||||
|
|
|
|||
17
app/src/main/java/com/tangem/data/network/TokenEmvApi.kt
Normal file
17
app/src/main/java/com/tangem/data/network/TokenEmvApi.kt
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.data.network
|
||||
|
||||
import com.tangem.data.network.model.TokenEmvGetTransferFeeAnswer
|
||||
import com.tangem.data.network.model.TokenEmvGetTransferFeeBody
|
||||
import com.tangem.data.network.model.TokenEmvTransferAnswer
|
||||
import com.tangem.data.network.model.TokenEmvTransferBody
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.Single
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface TokenEmvApi {
|
||||
@POST("./card/transfer")
|
||||
fun transfer(@Body tokenEmvTransferBody: TokenEmvTransferBody): Single<TokenEmvTransferAnswer>
|
||||
@POST("./card/transfer/fee")
|
||||
fun getTransferFee(@Body tokenEmvGetTransferFeeBody: TokenEmvGetTransferFeeBody): Single<TokenEmvGetTransferFeeAnswer>
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.data.network.model
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
data class TokenEmvTransferBody(
|
||||
val CID: String,
|
||||
val publicKey: String,
|
||||
val amount: String,
|
||||
val currency: String,
|
||||
val recipient: String,
|
||||
@SerializedName("fee_limit")
|
||||
val feeLimit: String,
|
||||
val sequence: Int,
|
||||
val signature: String
|
||||
)
|
||||
|
||||
data class TokenEmvTransferAnswer(
|
||||
val error: String?,
|
||||
val errorCode: Int?,
|
||||
val success: Boolean?,
|
||||
val tx_id: String?,
|
||||
val blockchain_tx_id: String?
|
||||
)
|
||||
|
||||
data class TokenEmvGetTransferFeeBody(
|
||||
val CID: String,
|
||||
val publicKey: String
|
||||
)
|
||||
|
||||
data class TokenEmvGetTransferFeeAnswer(
|
||||
val error: String?,
|
||||
val errorCode: Int?,
|
||||
val success: Boolean?,
|
||||
val fee: String?,
|
||||
val currency: String?
|
||||
)
|
||||
|
|
@ -17,6 +17,9 @@ interface NetworkComponent {
|
|||
@get:Named(Server.ApiInfuraTestnet.URL_INFURA_TESTNET)
|
||||
val retrofitInfuraTestnet: Retrofit
|
||||
|
||||
@get:Named(Server.ApiInfuraRopsten.URL_INFURA_ROPSTEN)
|
||||
val retrofitInfuraRopsten: Retrofit
|
||||
|
||||
@get:Named(Server.ApiMaticTesnet.URL_MATIC_TESTNET)
|
||||
val retrofitMaticTesnet: Retrofit
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,18 @@ internal class NetworkModule {
|
|||
return builder.build()
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
@Named(Server.ApiInfuraRopsten.URL_INFURA_ROPSTEN)
|
||||
fun provideRetrofitInfuraRopsten(): Retrofit {
|
||||
val builder = Retrofit.Builder()
|
||||
.baseUrl(Server.ApiInfuraRopsten.URL_INFURA_ROPSTEN)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
if (BuildConfig.DEBUG)
|
||||
builder.client(createOkHttpClient())
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
@Named(Server.ApiRootstock.URL_ROOTSTOCK)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import androidx.core.os.bundleOf
|
|||
import androidx.lifecycle.ViewModelProviders
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.google.firebase.perf.FirebasePerformance
|
||||
import com.google.firebase.perf.metrics.Trace
|
||||
import com.tangem.App
|
||||
import com.tangem.Constant
|
||||
import com.tangem.data.Blockchain
|
||||
|
|
@ -77,6 +79,7 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader
|
|||
override val layoutId = R.layout.fragment_main
|
||||
private lateinit var viewModel: MainViewModel
|
||||
private lateinit var nfcDeviceAntenna: NfcDeviceAntennaLocation
|
||||
private var tapTimerTrace: Trace? = null
|
||||
private var unsuccessReadCount = 0
|
||||
private var task: CustomReadCardTask? = null
|
||||
private var lastTag: Tag? = null
|
||||
|
|
@ -156,6 +159,9 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader
|
|||
}
|
||||
|
||||
override fun onResume() {
|
||||
tapTimerTrace = FirebasePerformance.getInstance()
|
||||
.newTrace(AnalyticsEvent.CARD_TAP_USER_TIMER.event)
|
||||
tapTimerTrace?.start()
|
||||
super.onResume()
|
||||
nfcDeviceAntenna.animate()
|
||||
}
|
||||
|
|
@ -167,6 +173,7 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader
|
|||
|
||||
override fun onStop() {
|
||||
task?.cancel(true)
|
||||
tapTimerTrace = null
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
|
|
@ -248,6 +255,7 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader
|
|||
}
|
||||
|
||||
override fun onReadFinish(cardProtocol: CardProtocol?) {
|
||||
tapTimerTrace?.stop()
|
||||
task = null
|
||||
if (cardProtocol != null) {
|
||||
if (cardProtocol.error == null) {
|
||||
|
|
@ -338,7 +346,7 @@ class MainFragment : BaseFragment(), NavigationResultListener, NfcAdapter.Reader
|
|||
|
||||
lastTag = null
|
||||
ReadCardInfoTask.resetLastReadInfo()
|
||||
(activity as MainActivity).nfcManager.notifyReadResult(false)
|
||||
(activity as? MainActivity)?.nfcManager?.notifyReadResult(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import androidx.preference.Preference
|
|||
import androidx.preference.PreferenceCategory
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.util.Analytics
|
||||
import com.tangem.util.AnalyticsEvent
|
||||
import com.tangem.wallet.BuildConfig
|
||||
|
|
@ -48,15 +47,13 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP
|
|||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
|
||||
if (key == getString(R.string.pref_analytics)) {
|
||||
activity?.let {
|
||||
val analytics = FirebaseAnalytics.getInstance(it)
|
||||
activity?.let {activity ->
|
||||
val analytics = FirebaseAnalytics.getInstance(activity)
|
||||
if (!Analytics.isEnabled()) {
|
||||
analytics.logEvent(AnalyticsEvent.ANALYTICS_TURNED_OFF.event, bundleOf())
|
||||
}
|
||||
analytics.setAnalyticsCollectionEnabled(Analytics.isEnabled() && !BuildConfig.DEBUG)
|
||||
Analytics.setFirebaseEnabled(activity)
|
||||
}
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(Analytics.isEnabled())
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
package com.tangem.util
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import androidx.core.os.bundleOf
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.google.firebase.perf.FirebasePerformance
|
||||
import com.tangem.data.dp.PrefsManager
|
||||
import com.tangem.wallet.BuildConfig
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.TangemContext
|
||||
|
||||
|
|
@ -13,6 +18,7 @@ enum class AnalyticsEvent(val event: String) {
|
|||
READY_TO_SIGN("ready_to_sign"),
|
||||
SIGNED("signed"),
|
||||
ANALYTICS_TURNED_OFF("analytics_turned_off"),
|
||||
CARD_TAP_USER_TIMER("CardTapUserTimer"),
|
||||
;
|
||||
}
|
||||
|
||||
|
|
@ -36,5 +42,13 @@ class Analytics {
|
|||
fun isEnabled(): Boolean {
|
||||
return PrefsManager.getInstance().getSettingsBoolean(R.string.pref_analytics, true)
|
||||
}
|
||||
|
||||
fun setFirebaseEnabled(context: Context, enable: Boolean = isEnabled()) {
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(enable)
|
||||
FirebaseAnalytics.getInstance(context).setAnalyticsCollectionEnabled(
|
||||
enable && !BuildConfig.DEBUG
|
||||
)
|
||||
FirebasePerformance.getInstance().isPerformanceCollectionEnabled = enable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import com.tangem.wallet.rsk.RskEngine
|
|||
import com.tangem.wallet.rsk.RskTokenEngine
|
||||
import com.tangem.wallet.token.TokenEngine
|
||||
import com.tangem.wallet.tezos.TezosEngine
|
||||
import com.tangem.wallet.tokenEmv.TokenEmvEngine
|
||||
import com.tangem.wallet.xlm.XlmAssetEngine
|
||||
import com.tangem.wallet.xlm.XlmEngine
|
||||
import com.tangem.wallet.xlmTag.XlmTagEngine
|
||||
|
|
@ -60,6 +61,7 @@ object CoinEngineFactory {
|
|||
Blockchain.Tezos -> TezosEngine()
|
||||
Blockchain.BitcoinDual -> BtcMultisigEngine()
|
||||
Blockchain.FlowDemo -> FlowDemoEngine()
|
||||
Blockchain.TokenEmv -> TokenEmvEngine()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
@ -109,6 +111,8 @@ object CoinEngineFactory {
|
|||
BtcMultisigEngine(context)
|
||||
else if (Blockchain.FlowDemo == context.blockchain)
|
||||
FlowDemoEngine(context)
|
||||
else if (Blockchain.TokenEmv == context.blockchain)
|
||||
TokenEmvEngine(context)
|
||||
else
|
||||
return null
|
||||
} catch (e: Exception) {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public class EthTransaction {
|
|||
return kec.digest(plainMsg);
|
||||
}
|
||||
|
||||
public int BruteRecoveryID2(ECDSASignatureETH sig, byte[] messageHash, byte[] thisKey) {
|
||||
public static int BruteRecoveryID2(ECDSASignatureETH sig, byte[] messageHash, byte[] thisKey) {
|
||||
Log.e("ETH_KZ", BTCUtils.toHex(thisKey));
|
||||
int recId = -1;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
|
|
|
|||
|
|
@ -8,31 +8,46 @@ import com.tangem.wallet.eth.EthData;
|
|||
|
||||
public class TokenData extends EthData {
|
||||
private CoinEngine.InternalAmount balanceAlter = null;
|
||||
|
||||
// private Integer sequence = null;
|
||||
|
||||
@Override
|
||||
public void clearInfo() {
|
||||
super.clearInfo();
|
||||
balanceAlter = null;
|
||||
// sequence = null;
|
||||
}
|
||||
|
||||
public CoinEngine.InternalAmount getBalanceAlterInInternalUnits() {
|
||||
return balanceAlter;
|
||||
|
||||
}
|
||||
|
||||
public void setBalanceAlterInInternalUnits(CoinEngine.InternalAmount value) {
|
||||
balanceAlter = value;
|
||||
}
|
||||
|
||||
// public Integer getSequence() {
|
||||
// return sequence;
|
||||
// }
|
||||
//
|
||||
// public void setSequence(Integer sequence) {
|
||||
// this.sequence = sequence;
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void loadFromBundle(Bundle B) {
|
||||
super.loadFromBundle(B);
|
||||
|
||||
if( B.containsKey("BalanceDecimalAlter" )) {
|
||||
if (B.containsKey("BalanceDecimalAlter")) {
|
||||
balanceAlter = new CoinEngine.InternalAmount(B.getString("BalanceDecimalAlter"), "wei");
|
||||
}else{
|
||||
balanceAlter=null;
|
||||
} else {
|
||||
balanceAlter = null;
|
||||
}
|
||||
// if (B.containsKey("Sequence")) {
|
||||
// sequence = B.getInt("Sequence");
|
||||
// } else {
|
||||
// sequence = null;
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -40,9 +55,12 @@ public class TokenData extends EthData {
|
|||
super.saveToBundle(B);
|
||||
|
||||
try {
|
||||
if( balanceAlter!=null ) {
|
||||
if (balanceAlter != null) {
|
||||
B.putString("BalanceDecimalAlter", balanceAlter.toString());
|
||||
}
|
||||
// if (sequence != null) {
|
||||
// B.putInt("Sequence", sequence);
|
||||
// }
|
||||
} catch (Exception e) {
|
||||
Log.e("Can't save to bundle ", e.getMessage());
|
||||
}
|
||||
|
|
|
|||
349
app/src/main/java/com/tangem/wallet/tokenEmv/TokenEmvEngine.kt
Normal file
349
app/src/main/java/com/tangem/wallet/tokenEmv/TokenEmvEngine.kt
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
package com.tangem.wallet.tokenEmv
|
||||
|
||||
import android.net.Uri
|
||||
import android.text.InputFilter
|
||||
import android.util.Log
|
||||
import com.google.gson.Gson
|
||||
import com.tangem.data.Blockchain
|
||||
import com.tangem.data.network.ServerApiInfura
|
||||
import com.tangem.data.network.ServerApiTokenEmv
|
||||
import com.tangem.data.network.model.*
|
||||
import com.tangem.tangem_card.data.TangemCard
|
||||
import com.tangem.tangem_card.reader.CardProtocol.TangemException
|
||||
import com.tangem.tangem_card.reader.TLV
|
||||
import com.tangem.tangem_card.reader.TLVList
|
||||
import com.tangem.tangem_card.tasks.SignTask
|
||||
import com.tangem.tangem_card.util.Util
|
||||
import com.tangem.util.DecimalDigitsInputFilter
|
||||
import com.tangem.wallet.EthTransaction
|
||||
import com.tangem.wallet.Keccak256
|
||||
import com.tangem.wallet.R
|
||||
import com.tangem.wallet.TangemContext
|
||||
import com.tangem.wallet.token.TokenEngine
|
||||
import io.reactivex.observers.DisposableSingleObserver
|
||||
import org.apache.commons.lang3.SerializationUtils
|
||||
import org.kethereum.extensions.toBytesPadded
|
||||
import java.math.BigInteger
|
||||
|
||||
class TokenEmvEngine : TokenEngine {
|
||||
constructor() : super()
|
||||
constructor(context: TangemContext) : super(context)
|
||||
|
||||
private val TAG = TokenEmvEngine::class.java.simpleName
|
||||
|
||||
private fun hasLinkedContract(): Boolean {
|
||||
return ctx.card.issuerData != null && ctx.card.issuerData.size == 44
|
||||
}
|
||||
|
||||
override fun getBlockchain(): Blockchain {
|
||||
return Blockchain.TokenEmv
|
||||
}
|
||||
|
||||
override fun getChainIdNum(): Int {
|
||||
return EthTransaction.ChainEnum.Ropsten.value
|
||||
}
|
||||
|
||||
override fun getBalance(): Amount? {
|
||||
return if (!hasBalanceInfo()) {
|
||||
null
|
||||
} else {
|
||||
convertToAmount(coinData.balanceInInternalUnits)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getBalanceHTML(): String? {
|
||||
return if (hasLinkedContract()) {
|
||||
if (balance != null) {
|
||||
balance!!.toDescriptionString(tokenDecimals)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
} else {
|
||||
"NO LINKED CONTRACT"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getBalanceCurrency(): String? {
|
||||
return ctx.card.getTokenSymbol()
|
||||
}
|
||||
|
||||
override fun getAmountInputFilters(): Array<InputFilter>? {
|
||||
return arrayOf(DecimalDigitsInputFilter(tokenDecimals))
|
||||
}
|
||||
|
||||
override fun getFeeCurrency(): String? {
|
||||
return balanceCurrency
|
||||
}
|
||||
|
||||
override fun isBalanceNotZero(): Boolean {
|
||||
if (coinData == null) return false
|
||||
return if (coinData.balanceInInternalUnits == null) {
|
||||
false
|
||||
} else {
|
||||
coinData.balanceInInternalUnits.notZero()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getBalanceEquivalent(): String? {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun evaluateFeeEquivalent(fee: String?): String? {
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun defineWallet() {
|
||||
try {
|
||||
if (hasLinkedContract()) {
|
||||
ctx.coinData.wallet = TLVList.fromBytes(ctx.card.issuerData).getTLV(TLV.Tag.TAG_Token_Contract_Address).asString
|
||||
} else {
|
||||
ctx.coinData.wallet = calculateAddress(ctx.card.walletPublicKey)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ctx.coinData.wallet = "ERROR"
|
||||
throw TangemException("Can't define wallet address")
|
||||
}
|
||||
}
|
||||
|
||||
override fun hasBalanceInfo(): Boolean {
|
||||
return coinData.balanceInInternalUnits != null
|
||||
}
|
||||
|
||||
override fun getWalletExplorerUri(): Uri {
|
||||
return Uri.parse("https://ropsten.etherscan.io/token/" + getContractAddress(ctx.card) + "?a=" + ctx.coinData.wallet)
|
||||
}
|
||||
|
||||
override fun isExtractPossible(): Boolean {
|
||||
if (!hasBalanceInfo()) {
|
||||
ctx.setMessage(R.string.loaded_wallet_error_obtaining_blockchain_data)
|
||||
} else if (!isBalanceNotZero) {
|
||||
ctx.setMessage(R.string.general_wallet_empty)
|
||||
} else if (awaitingConfirmation()) {
|
||||
ctx.setMessage(R.string.loaded_wallet_message_wait)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun checkNewTransactionAmountAndFee(amount: Amount, fee: Amount?, isFeeIncluded: Boolean): Boolean {
|
||||
try {
|
||||
if (isFeeIncluded && (amount > balance || amount < fee)) return false
|
||||
if (!isFeeIncluded && amount.add(fee) > balance) return false
|
||||
} catch (e: NumberFormatException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun constructTransaction(amountValue: Amount, feeValue: Amount?, IncFee: Boolean, targetAddress: String?): SignTask.TransactionToSign? {
|
||||
val functionBytes = "transfer".toByteArray()
|
||||
|
||||
val contractHex = coinData.wallet.substring(2)
|
||||
val contractBytes = Util.hexToBytes(contractHex)
|
||||
val recipientHex = targetAddress!!.substring(2)
|
||||
val recipientBytes = Util.hexToBytes(recipientHex)
|
||||
|
||||
val amountBytes = convertToInternalAmount(amountValue).toBigInteger().toBytesPadded(32)
|
||||
val feeLimitBytes = convertToInternalAmount(feeValue).toBigInteger().toBytesPadded(32)
|
||||
|
||||
val sequence = ctx.card.SignedHashes
|
||||
val sequenceBytes = sequence.toBigInteger().toBytesPadded(4)
|
||||
|
||||
val hashToSign = Keccak256().digest(contractBytes + functionBytes + amountBytes + recipientBytes + feeLimitBytes + sequenceBytes)
|
||||
|
||||
return object : SignTask.TransactionToSign {
|
||||
override fun isSigningMethodSupported(signingMethod: TangemCard.SigningMethod): Boolean {
|
||||
return signingMethod == TangemCard.SigningMethod.Sign_Hash
|
||||
}
|
||||
|
||||
override fun getHashesToSign(): Array<ByteArray> {
|
||||
return arrayOf(hashToSign)
|
||||
}
|
||||
|
||||
@Throws(java.lang.Exception::class)
|
||||
override fun getRawDataToSign(): ByteArray {
|
||||
throw java.lang.Exception("Signing of raw transaction not supported for " + this.javaClass.simpleName)
|
||||
}
|
||||
|
||||
@Throws(java.lang.Exception::class)
|
||||
override fun getHashAlgToSign(): String {
|
||||
throw java.lang.Exception("Signing of raw transaction not supported for " + this.javaClass.simpleName)
|
||||
}
|
||||
|
||||
@Throws(java.lang.Exception::class)
|
||||
override fun getIssuerTransactionSignature(dataToSignByIssuer: ByteArray): ByteArray {
|
||||
throw java.lang.Exception("Transaction validation by issuer not supported in this version")
|
||||
}
|
||||
|
||||
@Throws(java.lang.Exception::class)
|
||||
override fun onSignCompleted(signFromCard: ByteArray): ByteArray {
|
||||
// val r = BigInteger(1, Arrays.copyOfRange(signFromCard, 0, 32))
|
||||
// var s: BigInteger? = BigInteger(1, Arrays.copyOfRange(signFromCard, 32, 64))
|
||||
// s = CryptoUtil.toCanonicalised(s)
|
||||
//
|
||||
// val publicKey = ctx.getCard().getWalletPublicKey()
|
||||
//
|
||||
// val verified = ECKey.verify(hashToSign, ECKey.ECDSASignature(r, s), publicKey)
|
||||
// if (!verified) {
|
||||
// Log.e(this.javaClass.simpleName + "-CHECK", "sign Failed.")
|
||||
// }
|
||||
//
|
||||
// val v = BruteRecoveryID2(ECDSASignatureETH(r, s), hashToSign, publicKey)
|
||||
// if (v != 27 && v != 28) {
|
||||
// Log.e(TAG, "invalid v")
|
||||
// throw java.lang.Exception("Error in " + this.javaClass.simpleName + " - invalid v")
|
||||
// }
|
||||
// Log.e(TAG, this.javaClass.simpleName + " V: " + v.toString())
|
||||
//
|
||||
// var rBytes = r.toByteArray()
|
||||
// if (rBytes.size == 33) {
|
||||
// rBytes = rBytes.copyOfRange(1,33)
|
||||
// }
|
||||
// val sBytes = s.toByteArray()
|
||||
//
|
||||
// val tokenEmvTransferBody = TokenEmvTransferBody(
|
||||
// CID = Util.bytesToHex(ctx.card.cid),
|
||||
// publicKey = Util.bytesToHex(ctx.card.walletPublicKey),
|
||||
// contract = contractHex,
|
||||
// amount = Util.byteArrayToHexString(amountBytes),
|
||||
// recipient = recipientHex,
|
||||
// feeLimit = Util.byteArrayToHexString(feeLimitBytes),
|
||||
// sequence = sequence,
|
||||
// r = Util.byteArrayToHexString(rBytes),
|
||||
// s = Util.byteArrayToHexString(sBytes),
|
||||
// v = v
|
||||
// )
|
||||
|
||||
val tokenEmvTransferBody = TokenEmvTransferBody(
|
||||
CID = Util.bytesToHex(ctx.card.cid),
|
||||
publicKey = Util.bytesToHex(ctx.card.walletPublicKey),
|
||||
amount = amountValue.toValueString(),
|
||||
currency = amountValue.currency,
|
||||
recipient = targetAddress,
|
||||
feeLimit = feeValue!!.toValueString(),
|
||||
sequence = sequence,
|
||||
signature = Util.bytesToHex(signFromCard)
|
||||
)
|
||||
|
||||
val jsonBody = Gson().toJson(tokenEmvTransferBody)
|
||||
val serializedBody = SerializationUtils.serialize(jsonBody)
|
||||
|
||||
notifyOnNeedSendTransaction(serializedBody)
|
||||
return serializedBody
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun requestBalanceAndUnspentTransactions(blockchainRequestsCallbacks: BlockchainRequestsCallbacks) {
|
||||
val serverApiInfura = ServerApiInfura(ctx.blockchain)
|
||||
|
||||
val responseListener: ServerApiInfura.ResponseListener = object : ServerApiInfura.ResponseListener {
|
||||
override fun onSuccess(method: String, infuraResponse: InfuraResponse) {
|
||||
try {
|
||||
var balanceCap = infuraResponse.result
|
||||
balanceCap = balanceCap!!.substring(2)
|
||||
val l = BigInteger(balanceCap, 16)
|
||||
coinData.balanceInInternalUnits = InternalAmount(l, ctx.card.tokenSymbol)
|
||||
coinData.isBalanceReceived = true
|
||||
// Log.i("$TAG eth_call", balanceCap)
|
||||
} catch (e: java.lang.Exception) {
|
||||
onFail(method, e.message ?: "invalid response")
|
||||
}
|
||||
blockchainRequestsCallbacks.onComplete(true)
|
||||
}
|
||||
|
||||
override fun onFail(method: String, message: String) {
|
||||
Log.e(TAG, "onFail: $method $message")
|
||||
ctx.error = message
|
||||
blockchainRequestsCallbacks.onComplete(false)
|
||||
}
|
||||
}
|
||||
|
||||
serverApiInfura.setResponseListener(responseListener)
|
||||
|
||||
if (validateAddress(getContractAddress(ctx.card))) {
|
||||
serverApiInfura.requestData(ServerApiInfura.INFURA_ETH_CALL, 67, coinData.wallet, getContractAddress(ctx.card), "")
|
||||
} else {
|
||||
ctx.error = "Smart contract address not defined"
|
||||
blockchainRequestsCallbacks.onComplete(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun requestFee(blockchainRequestsCallbacks: BlockchainRequestsCallbacks, targetAddress: String?, amount: Amount) {
|
||||
|
||||
val tokenEmvTransferBody = TokenEmvGetTransferFeeBody(
|
||||
CID = Util.bytesToHex(ctx.card.cid),
|
||||
publicKey = Util.bytesToHex(ctx.card.walletPublicKey)
|
||||
)
|
||||
|
||||
val observer = object : DisposableSingleObserver<TokenEmvGetTransferFeeAnswer>() {
|
||||
override fun onError(e: Throwable) {
|
||||
ctx.error = "Can't get transfer fee, ${e.message}"
|
||||
blockchainRequestsCallbacks.onComplete(false)
|
||||
}
|
||||
|
||||
override fun onSuccess(t: TokenEmvGetTransferFeeAnswer) {
|
||||
if (t.success != null && t.success) {
|
||||
ctx.error = null
|
||||
coinData.minFee = Amount(t.fee, t.currency)
|
||||
coinData.normalFee = Amount(t.fee, t.currency)
|
||||
coinData.maxFee = Amount(t.fee, t.currency)
|
||||
blockchainRequestsCallbacks.onComplete(true)
|
||||
} else {
|
||||
if (t.error != null) {
|
||||
ctx.error = t.error
|
||||
} else {
|
||||
ctx.error = "Can't get transfer fee, code ${t.errorCode}"
|
||||
}
|
||||
blockchainRequestsCallbacks.onComplete(false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ServerApiTokenEmv().getTransferFee(tokenEmvTransferBody, observer)
|
||||
blockchainRequestsCallbacks.onComplete(true)
|
||||
}
|
||||
|
||||
override fun requestSendTransaction(blockchainRequestsCallbacks: BlockchainRequestsCallbacks, txForSend: ByteArray?) {
|
||||
val jsonBody = SerializationUtils.deserialize<String>(txForSend)
|
||||
|
||||
Log.e(TAG, jsonBody)
|
||||
|
||||
val tokenEmvTransferBody = Gson().fromJson(jsonBody, TokenEmvTransferBody::class.java)
|
||||
|
||||
val observer = object : DisposableSingleObserver<TokenEmvTransferAnswer>() {
|
||||
override fun onError(e: Throwable) {
|
||||
ctx.error = "Can't send transfer, ${e.message}"
|
||||
blockchainRequestsCallbacks.onComplete(false)
|
||||
}
|
||||
|
||||
override fun onSuccess(t: TokenEmvTransferAnswer) {
|
||||
if (t.success != null && t.success) {
|
||||
ctx.error = null
|
||||
blockchainRequestsCallbacks.onComplete(true)
|
||||
} else {
|
||||
if (t.error != null) {
|
||||
ctx.error = t.error
|
||||
} else {
|
||||
ctx.error = "Can't send transfer, code ${t.errorCode}"
|
||||
}
|
||||
blockchainRequestsCallbacks.onComplete(false)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
ServerApiTokenEmv().transfer(tokenEmvTransferBody, observer)
|
||||
}
|
||||
|
||||
override fun allowSelectFeeLevel(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun pendingTransactionTimeoutInSeconds(): Int {
|
||||
return 60
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -24,6 +24,10 @@ android {
|
|||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
|
|
@ -80,6 +84,17 @@ dependencies {
|
|||
implementation 'org.json:json:20180813'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
|
||||
|
||||
//dependencies for binance
|
||||
implementation 'com.google.protobuf:protobuf-java:3.6.1'
|
||||
implementation 'io.grpc:grpc-protobuf:1.17.1'
|
||||
implementation 'io.grpc:grpc-stub:1.17.1'
|
||||
implementation 'commons-codec:commons-codec:1.10'
|
||||
implementation 'org.apache.commons:commons-lang3:3.6'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-joda:2.9.8'
|
||||
implementation 'joda-time:joda-time:2.10.1'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
implementation 'com.squareup.retrofit2:converter-jackson:2.6.0'
|
||||
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.5.2'
|
||||
testImplementation "com.google.truth:truth:1.0"
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
package com.tangem.blockchain.binance
|
||||
|
||||
import com.tangem.blockchain.binance.client.encoding.Crypto
|
||||
import com.tangem.common.extensions.calculateRipemd160
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import com.tangem.common.extensions.toCompressedPublicKey
|
||||
import org.bitcoinj.core.Bech32
|
||||
|
||||
class BinanceAddressFactory {
|
||||
companion object {
|
||||
fun makeAddress(walletPublicKey: ByteArray, testNet: Boolean = false): String {
|
||||
val publicKeyHash = walletPublicKey.toCompressedPublicKey().calculateSha256().calculateRipemd160()
|
||||
return if (testNet) {
|
||||
Bech32.encode("tbnb", Crypto.convertBits(publicKeyHash, 0, publicKeyHash.size, 8, 5, false))
|
||||
} else {
|
||||
Bech32.encode("bnb", Crypto.convertBits(publicKeyHash, 0, publicKeyHash.size, 8, 5, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BinanceAddressValidator {
|
||||
companion object {
|
||||
fun validate(address: String, testNet: Boolean = false): Boolean {
|
||||
return try {
|
||||
Crypto.decodeAddress(address)
|
||||
if (testNet) {
|
||||
address.startsWith("tbnb1")
|
||||
} else {
|
||||
address.startsWith("bnb1")
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.tangem.blockchain.binance
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexApiClientFactory
|
||||
import com.tangem.blockchain.binance.client.BinanceDexEnvironment
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TransactionOption
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.Transfer
|
||||
import com.tangem.blockchain.binance.client.encoding.message.MessageType
|
||||
import com.tangem.blockchain.binance.client.encoding.message.TransactionRequestAssemblerExtSign
|
||||
import com.tangem.blockchain.binance.client.encoding.message.TransferMessage
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import com.tangem.common.extensions.toCompressedPublicKey
|
||||
import org.bitcoinj.core.ECKey
|
||||
import org.bitcoinj.core.Utils
|
||||
import java.math.BigInteger
|
||||
|
||||
class BinanceTransactionBuilder(publicKey: ByteArray, isTestNet: Boolean) {
|
||||
val chainId = if (isTestNet) "Binance-Chain-Nile" else "Binance-Chain-Tigris"
|
||||
val prefixedPubKey = MessageType.PubKey.typePrefixBytes + 33.toByte() + publicKey.toCompressedPublicKey()
|
||||
val client = BinanceDexApiClientFactory.newInstance().newRestClient(
|
||||
if (isTestNet) BinanceDexEnvironment.PROD.baseUrl else BinanceDexEnvironment.TEST_NET.baseUrl
|
||||
)
|
||||
|
||||
var accountNumber: Long? = null
|
||||
var sequence: Long? = null
|
||||
var transactionAssembler: TransactionRequestAssemblerExtSign? = null
|
||||
var transferMessage: TransferMessage? = null
|
||||
|
||||
fun buildToSign(transactionData: TransactionData): ByteArray {
|
||||
val transfer = Transfer()
|
||||
transfer.coin = transactionData.amount.currencySymbol
|
||||
transfer.fromAddress = transactionData.sourceAddress
|
||||
transfer.toAddress = transactionData.destinationAddress
|
||||
transfer.amount = transactionData.amount.value!!
|
||||
.setScale(Blockchain.Binance.decimals.toInt()).toPlainString()
|
||||
|
||||
val options = TransactionOption.DEFAULT_INSTANCE
|
||||
|
||||
val accountData = BinanceAccountData(chainId, accountNumber!!, sequence!!)
|
||||
|
||||
transactionAssembler = client.prepareTransfer(transfer, accountData, prefixedPubKey, options, true)
|
||||
transferMessage = transactionAssembler!!.createTransferMessage(transfer)
|
||||
|
||||
return transactionAssembler!!.prepareForSign(transferMessage).calculateSha256()
|
||||
}
|
||||
|
||||
fun buildToSend(signature: ByteArray): ByteArray {
|
||||
val r = BigInteger(1, signature.copyOfRange(0, 32))
|
||||
val s = BigInteger(1, signature.copyOfRange(32, 64))
|
||||
val canonicalS = ECKey.ECDSASignature(r, s).toCanonicalised().s
|
||||
|
||||
//bigIntegerToBytes cuts leading zero if present
|
||||
val canonicalSignature = Utils.bigIntegerToBytes(r, 32) + Utils.bigIntegerToBytes(canonicalS, 32)
|
||||
val encodedSignature = transactionAssembler!!.encodeSignature(canonicalSignature)
|
||||
|
||||
val encodedTransferMessage = transactionAssembler!!.encodeTransferMessage(transferMessage)
|
||||
|
||||
return transactionAssembler!!.encodeStdTx(encodedTransferMessage, encodedSignature)
|
||||
}
|
||||
}
|
||||
|
||||
data class BinanceAccountData(
|
||||
val chainId: String,
|
||||
val accountNumber: Long,
|
||||
val sequence: Long
|
||||
)
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package com.tangem.blockchain.binance
|
||||
|
||||
import android.util.Log
|
||||
import com.tangem.blockchain.binance.network.BinanceInfoResponse
|
||||
import com.tangem.blockchain.binance.network.BinanceNetworkManager
|
||||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.common.extensions.Result
|
||||
import com.tangem.blockchain.common.extensions.SimpleResult
|
||||
import com.tangem.blockchain.wallets.CurrencyWallet
|
||||
import com.tangem.common.CompletionResult
|
||||
|
||||
class BinanceWalletManager(
|
||||
private val cardId: String,
|
||||
walletPublicKey: ByteArray,
|
||||
override var wallet: CurrencyWallet,
|
||||
isTestNet: Boolean = false
|
||||
) : WalletManager,
|
||||
TransactionSender,
|
||||
FeeProvider {
|
||||
|
||||
override val blockchain = if (isTestNet) Blockchain.BinanceTestnet else Blockchain.Binance
|
||||
private val address = blockchain.makeAddress(walletPublicKey)
|
||||
private val transactionBuilder = BinanceTransactionBuilder(walletPublicKey, isTestNet)
|
||||
private val networkManager = BinanceNetworkManager(isTestNet)
|
||||
|
||||
init {
|
||||
wallet.balances[AmountType.Coin] = Amount(null, blockchain, address)
|
||||
}
|
||||
|
||||
override suspend fun update() {
|
||||
val result = networkManager.getInfo(address)
|
||||
when (result) {
|
||||
is Result.Success -> updateWallet(result.data)
|
||||
is Result.Failure -> updateError(result.error)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateWallet(response: BinanceInfoResponse) {
|
||||
Log.d(this::class.java.simpleName, "Balance is ${response.balance}")
|
||||
wallet.balances[AmountType.Coin]?.value = response.balance
|
||||
|
||||
transactionBuilder.accountNumber = response.accountNumber
|
||||
transactionBuilder.sequence = response.sequence
|
||||
}
|
||||
|
||||
private fun updateError(error: Throwable?) {
|
||||
Log.e(this::class.java.simpleName, error?.message ?: "")
|
||||
if (error != null) throw error
|
||||
}
|
||||
|
||||
override suspend fun send(transactionData: TransactionData, signer: TransactionSigner): SimpleResult {
|
||||
val transactionHash = transactionBuilder.buildToSign(transactionData)
|
||||
|
||||
when (val signerResponse = signer.sign(arrayOf(transactionHash), cardId)) {
|
||||
is CompletionResult.Success -> {
|
||||
val transactionToSend = transactionBuilder.buildToSend(signerResponse.data.signature)
|
||||
return networkManager.sendTransaction(transactionToSend)
|
||||
}
|
||||
is CompletionResult.Failure -> return SimpleResult.Failure(signerResponse.error)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getFee(amount: Amount, destination: String): Result<List<Amount>> {
|
||||
when (val result = networkManager.getFee()) {
|
||||
is Result.Success -> return Result.Success(listOf(Amount(result.data, blockchain)))
|
||||
is Result.Failure -> return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.tangem.blockchain.binance.client.domain.*;
|
||||
import okhttp3.RequestBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BinanceDexApi {
|
||||
@GET("/api/v1/time")
|
||||
Call<Time> getTime();
|
||||
|
||||
@GET("/api/v1/node-info")
|
||||
Call<Infos> getNodeInfo();
|
||||
|
||||
@GET("/api/v1/validators")
|
||||
Call<Validators> getValidators();
|
||||
|
||||
@GET("/api/v1/peers")
|
||||
Call<List<Peer>> getPeers();
|
||||
|
||||
@GET("/api/v1/account/{address}")
|
||||
Call<Account> getAccount(@Path("address") String address);
|
||||
|
||||
@GET("/api/v1/account/{address}/sequence")
|
||||
Call<AccountSequence> getAccountSequence(@Path("address") String address);
|
||||
|
||||
@GET("/api/v1/tx/{hash}")
|
||||
Call<TransactionMetadata> getTransactionMetadata(@Path("hash") String hash);
|
||||
|
||||
@GET("/api/v1/tokens")
|
||||
Call<List<Token>> getTokens();
|
||||
|
||||
@GET("/api/v1/markets")
|
||||
Call<List<Market>> getMarkets();
|
||||
|
||||
|
||||
@GET("/api/v1/depth")
|
||||
Call<OrderBook> getOrderBook(@Query("symbol") String symbol, @Query("limit") Integer limit);
|
||||
|
||||
@GET("/api/v1/klines")
|
||||
Call<List<Candlestick>> getCandlestickBars(@Query("symbol") String symbol, @Query("interval") String interval,
|
||||
@Query("limit") Integer limit, @Query("startTime") Long startTime,
|
||||
@Query("endTime") Long endTime);
|
||||
|
||||
@GET("/api/v1/orders/open")
|
||||
Call<OrderList> getOpenOrders(@Query("address") String address, @Query("limit") Integer limit,
|
||||
@Query("offset") Integer offset, @Query("symbol") String symbol,
|
||||
@Query("total") Integer total);
|
||||
|
||||
@GET("/api/v1/orders/closed")
|
||||
Call<OrderList> getClosedOrders(@Query("address") String address, @Query("end") Long end,
|
||||
@Query("limit") Integer limit, @Query("offset") Integer offset,
|
||||
@Query("side") String side, @Query("start") Long start,
|
||||
@Query("status") List<String> status, @Query("symbol") String symbol,
|
||||
@Query("total") Integer total);
|
||||
|
||||
@GET("/api/v1/orders/{id}")
|
||||
Call<Order> getOrder(@Path("id") String id);
|
||||
|
||||
@GET("/api/v1/ticker/24hr")
|
||||
Call<List<TickerStatistics>> get24HrPriceStatistics();
|
||||
|
||||
@GET("/api/v1/trades")
|
||||
Call<TradePage> getTrades(@Query("address") String address,
|
||||
@Query("buyerOrderId") String buyerOrderId, @Query("end") Long end,
|
||||
@Query("height") Long height, @Query("limit") Integer limit,
|
||||
@Query("offset") Integer offset, @Query("quoteAsset") String quoteAsset,
|
||||
@Query("sellerOrderId") String sellerOrderId, @Query("side") String side,
|
||||
@Query("start") Long start, @Query("symbol") String symbol, @Query("total") Integer total);
|
||||
|
||||
@GET("/api/v1/transactions")
|
||||
Call<TransactionPage> getTransactions(@Query("address") String address, @Query("blockHeight") Long blockHeight,
|
||||
@Query("endTime") Long endTime, @Query("limit") Integer limit,
|
||||
@Query("offset") Integer offset, @Query("side") String side,
|
||||
@Query("startTime") Long startTime, @Query("txAsset") String txAsset,
|
||||
@Query("txType") String txType);
|
||||
|
||||
@POST("/api/v1/broadcast")
|
||||
Call<List<TransactionMetadata>> broadcast(@Query("sync") boolean sync, @Body RequestBody transaction);
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import com.tangem.blockchain.binance.client.domain.*;
|
||||
import com.tangem.blockchain.binance.client.domain.request.ClosedOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.OpenOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TradesRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TransactionsRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BinanceDexApiAsyncRestClient {
|
||||
void getTime(BinanceDexApiCallback<Time> callback);
|
||||
|
||||
void getNodeInfo(BinanceDexApiCallback<Infos> callback);
|
||||
|
||||
void getValidators(BinanceDexApiCallback<Validators> callback);
|
||||
|
||||
void getPeers(BinanceDexApiCallback<List<Peer>> callback);
|
||||
|
||||
void getMarkets(BinanceDexApiCallback<List<Market>> callback);
|
||||
|
||||
void getAccount(String address, BinanceDexApiCallback<Account> callback);
|
||||
|
||||
void getAccountSequence(String address, BinanceDexApiCallback<AccountSequence> callback);
|
||||
|
||||
void getTransactionMetadata(String hash, BinanceDexApiCallback<TransactionMetadata> callback);
|
||||
|
||||
void getTokens(BinanceDexApiCallback<List<Token>> callback);
|
||||
|
||||
void getOrderBook(String symbol, Integer limit, BinanceDexApiCallback<OrderBook> callback);
|
||||
|
||||
void getCandleStickBars(String symbol, CandlestickInterval interval,
|
||||
BinanceDexApiCallback<List<Candlestick>> callback);
|
||||
|
||||
void getCandleStickBars(String symbol, CandlestickInterval interval, Integer limit, Long startTime, Long endTime,
|
||||
BinanceDexApiCallback<List<Candlestick>> callback);
|
||||
|
||||
void getOpenOrders(String address, BinanceDexApiCallback<OrderList> callback);
|
||||
|
||||
void getOpenOrders(OpenOrdersRequest request, BinanceDexApiCallback<OrderList> callback);
|
||||
|
||||
void getClosedOrders(String address, BinanceDexApiCallback<OrderList> callback);
|
||||
|
||||
void getClosedOrders(ClosedOrdersRequest request, BinanceDexApiCallback<OrderList> callback);
|
||||
|
||||
void getOrder(String id, BinanceDexApiCallback<Order> callback);
|
||||
|
||||
void get24HrPriceStatistics(BinanceDexApiCallback<List<TickerStatistics>> callback);
|
||||
|
||||
void getTrades(BinanceDexApiCallback<TradePage> callback);
|
||||
|
||||
void getTrades(TradesRequest request, BinanceDexApiCallback<TradePage> callback);
|
||||
|
||||
void getTransactions(String address, BinanceDexApiCallback<TransactionPage> callback);
|
||||
|
||||
void getTransactions(TransactionsRequest request, BinanceDexApiCallback<TransactionPage> callback);
|
||||
|
||||
// Do not support async broadcast due to account sequence
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
/**
|
||||
* BinanceDexApiCallback is a functional interface used together with the BinanceApiAsyncClient to provide a non-blocking REST client.
|
||||
*
|
||||
* @param <T> the return type from the callback
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BinanceDexApiCallback<T> {
|
||||
|
||||
/**
|
||||
* Called whenever a response comes back from the Binance API.
|
||||
*
|
||||
* @param response the expected response object
|
||||
*/
|
||||
void onResponse(T response);
|
||||
|
||||
/**
|
||||
* Called whenever an error occurs.
|
||||
*
|
||||
* @param cause the cause of the failure
|
||||
*/
|
||||
default void onFailure(Throwable cause) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
import static com.tangem.blockchain.binance.client.BinanceDexApiClientGenerator.getBinanceApiError;
|
||||
|
||||
/**
|
||||
* An adapter/wrapper which transforms a Callback from Retrofit into a BinanceDexApiCallback which is exposed to the client.
|
||||
*/
|
||||
public class BinanceDexApiCallbackAdapter<T> implements Callback<T> {
|
||||
|
||||
private final BinanceDexApiCallback<T> callback;
|
||||
|
||||
public BinanceDexApiCallbackAdapter(BinanceDexApiCallback<T> callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void onResponse(Call<T> call, Response<T> response) {
|
||||
if (response.isSuccessful()) {
|
||||
callback.onResponse(response.body());
|
||||
} else {
|
||||
if (response.code() == 504) {
|
||||
// HTTP 504 return code is used when the API successfully sent the message but not get a response within the timeout period.
|
||||
// It is important to NOT treat this as a failure; the execution status is UNKNOWN and could have been a success.
|
||||
return;
|
||||
}
|
||||
try {
|
||||
BinanceDexApiError apiError = getBinanceApiError(response);
|
||||
onFailure(call, new BinanceDexApiException(apiError));
|
||||
} catch (IOException e) {
|
||||
onFailure(call, new BinanceDexApiException(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<T> call, Throwable throwable) {
|
||||
if (throwable instanceof BinanceDexApiException) {
|
||||
callback.onFailure(throwable);
|
||||
} else {
|
||||
callback.onFailure(new BinanceDexApiException(throwable));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import com.tangem.blockchain.binance.client.impl.BinanceDexApiAsyncRestClientImpl;
|
||||
import com.tangem.blockchain.binance.client.impl.BinanceDexApiRestClientImpl;
|
||||
|
||||
public class BinanceDexApiClientFactory {
|
||||
private BinanceDexApiClientFactory() {
|
||||
}
|
||||
|
||||
public static BinanceDexApiClientFactory newInstance() {
|
||||
return new BinanceDexApiClientFactory();
|
||||
}
|
||||
|
||||
public BinanceDexApiRestClient newRestClient() {
|
||||
return newRestClient(BinanceDexEnvironment.PROD.getBaseUrl());
|
||||
}
|
||||
|
||||
public BinanceDexApiRestClient newRestClient(String baseUrl) {
|
||||
return new BinanceDexApiRestClientImpl(baseUrl);
|
||||
}
|
||||
|
||||
public BinanceDexApiAsyncRestClient newAsyncRestClient() {
|
||||
return newAsyncRestClient(BinanceDexEnvironment.PROD.getBaseUrl());
|
||||
}
|
||||
|
||||
public BinanceDexApiAsyncRestClient newAsyncRestClient(String baseUrl) {
|
||||
return new BinanceDexApiAsyncRestClientImpl(baseUrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.ResponseBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Converter;
|
||||
import retrofit2.Response;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.jackson.JacksonConverterFactory;
|
||||
|
||||
public class BinanceDexApiClientGenerator {
|
||||
private static final OkHttpClient sharedClient = new OkHttpClient.Builder()
|
||||
.pingInterval(20, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
private static final Converter.Factory converterFactory =
|
||||
JacksonConverterFactory.create(new ObjectMapper().registerModule(new JodaModule()));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Converter<ResponseBody, BinanceDexApiError> errorBodyConverter =
|
||||
(Converter<ResponseBody, BinanceDexApiError>) converterFactory.responseBodyConverter(
|
||||
BinanceDexApiError.class, new Annotation[0], null);
|
||||
|
||||
public static <S> S createService(Class<S> serviceClass, String baseUrl) {
|
||||
Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.addConverterFactory(converterFactory);
|
||||
|
||||
retrofitBuilder.client(sharedClient);
|
||||
|
||||
Retrofit retrofit = retrofitBuilder.build();
|
||||
|
||||
return retrofit.create(serviceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a REST call and block until the response is received.
|
||||
*/
|
||||
public static <T> T executeSync(Call<T> call) {
|
||||
try {
|
||||
Response<T> response = call.execute();
|
||||
if (response.isSuccessful()) {
|
||||
return response.body();
|
||||
} else {
|
||||
try {
|
||||
BinanceDexApiError apiError = getBinanceApiError(response);
|
||||
throw new BinanceDexApiException(apiError);
|
||||
} catch (IOException e) {
|
||||
throw new BinanceDexApiException(response.toString(), e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new BinanceDexApiException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts and converts the response error body into an object.
|
||||
*/
|
||||
public static BinanceDexApiError getBinanceApiError(Response<?> response) throws IOException {
|
||||
return errorBodyConverter.convert(response.errorBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared OkHttpClient instance.
|
||||
*/
|
||||
public static OkHttpClient getSharedClient() {
|
||||
return sharedClient;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class BinanceDexApiError {
|
||||
private int code;
|
||||
private String message;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||
.append("code", code)
|
||||
.append("message", message)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
|
||||
public class BinanceDexApiException extends RuntimeException {
|
||||
private static final long serialVersionUID = 3788669840036201041L;
|
||||
private BinanceDexApiError error;
|
||||
|
||||
public BinanceDexApiException(BinanceDexApiError error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public BinanceDexApiException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public BinanceDexApiException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public BinanceDexApiError getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
if (error != null) {
|
||||
return error.getMessage();
|
||||
}
|
||||
return super.getMessage();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import com.tangem.blockchain.binance.BinanceAccountData;
|
||||
import com.tangem.blockchain.binance.client.domain.Account;
|
||||
import com.tangem.blockchain.binance.client.domain.AccountSequence;
|
||||
import com.tangem.blockchain.binance.client.domain.Candlestick;
|
||||
import com.tangem.blockchain.binance.client.domain.CandlestickInterval;
|
||||
import com.tangem.blockchain.binance.client.domain.Infos;
|
||||
import com.tangem.blockchain.binance.client.domain.Market;
|
||||
import com.tangem.blockchain.binance.client.domain.Order;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderBook;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderList;
|
||||
import com.tangem.blockchain.binance.client.domain.Peer;
|
||||
import com.tangem.blockchain.binance.client.domain.TickerStatistics;
|
||||
import com.tangem.blockchain.binance.client.domain.Time;
|
||||
import com.tangem.blockchain.binance.client.domain.Token;
|
||||
import com.tangem.blockchain.binance.client.domain.TradePage;
|
||||
import com.tangem.blockchain.binance.client.domain.TransactionMetadata;
|
||||
import com.tangem.blockchain.binance.client.domain.TransactionPage;
|
||||
import com.tangem.blockchain.binance.client.domain.Validators;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.CancelOrder;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.NewOrder;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TokenFreeze;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TokenUnfreeze;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TransactionOption;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.Transfer;
|
||||
import com.tangem.blockchain.binance.client.domain.request.ClosedOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.OpenOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TradesRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TransactionsRequest;
|
||||
import com.tangem.blockchain.binance.client.encoding.message.TransactionRequestAssemblerExtSign;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
public interface BinanceDexApiRestClient {
|
||||
Time getTime();
|
||||
|
||||
Infos getNodeInfo();
|
||||
|
||||
Validators getValidators();
|
||||
|
||||
List<Peer> getPeers();
|
||||
|
||||
List<Market> getMarkets();
|
||||
|
||||
Account getAccount(String address);
|
||||
|
||||
AccountSequence getAccountSequence(String address);
|
||||
|
||||
TransactionMetadata getTransactionMetadata(String hash);
|
||||
|
||||
List<Token> getTokens();
|
||||
|
||||
OrderBook getOrderBook(String symbol, Integer limit);
|
||||
|
||||
List<Candlestick> getCandleStickBars(String symbol, CandlestickInterval interval);
|
||||
|
||||
List<Candlestick> getCandleStickBars(String symbol, CandlestickInterval interval, Integer limit, Long startTime, Long endTime);
|
||||
|
||||
OrderList getOpenOrders(String address);
|
||||
|
||||
OrderList getOpenOrders(OpenOrdersRequest request);
|
||||
|
||||
OrderList getClosedOrders(String address);
|
||||
|
||||
OrderList getClosedOrders(ClosedOrdersRequest request);
|
||||
|
||||
Order getOrder(String id);
|
||||
|
||||
List<TickerStatistics> get24HrPriceStatistics();
|
||||
|
||||
TradePage getTrades();
|
||||
|
||||
TradePage getTrades(TradesRequest request);
|
||||
|
||||
TransactionPage getTransactions(String address);
|
||||
|
||||
TransactionPage getTransactions(TransactionsRequest request);
|
||||
|
||||
public List<TransactionMetadata> broadcastNoWallet(RequestBody requestBody, boolean sync) throws BinanceDexApiException;
|
||||
|
||||
List<TransactionMetadata> newOrder(NewOrder newOrder, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException;
|
||||
|
||||
List<TransactionMetadata> cancelOrder(CancelOrder cancelOrder, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException;
|
||||
|
||||
List<TransactionMetadata> transfer(Transfer transfer, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException;
|
||||
|
||||
TransactionRequestAssemblerExtSign prepareTransfer(Transfer transfer, BinanceAccountData binanceAccountData, byte[] pubKeyForSign, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException;
|
||||
|
||||
List<TransactionMetadata> freeze(TokenFreeze freeze, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException;
|
||||
|
||||
List<TransactionMetadata> unfreeze(TokenUnfreeze unfreeze, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class BinanceDexConstants {
|
||||
|
||||
/**
|
||||
* Identifier of this client.
|
||||
*/
|
||||
public static final long BINANCE_DEX_API_CLIENT_JAVA_SOURCE = 3L;
|
||||
|
||||
/**
|
||||
* Default ToStringStyle used by toString methods.
|
||||
* Override this to change the output format of the overridden toString methods.
|
||||
* - Example ToStringStyle.JSON_STYLE
|
||||
*/
|
||||
public static final ToStringStyle BINANCE_DEX_TO_STRING_STYLE = ToStringStyle.SHORT_PREFIX_STYLE;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
public enum BinanceDexEnvironment {
|
||||
PROD(
|
||||
"https://dex.binance.org",
|
||||
"wss://dex.binance.org/api/",
|
||||
"bnb"
|
||||
),
|
||||
TEST_NET(
|
||||
"https://testnet-dex.binance.org",
|
||||
"wss://testnet-dex.binance.org/api/",
|
||||
"tbnb"
|
||||
);
|
||||
// Rest API base URL
|
||||
private String baseUrl;
|
||||
// Websocket API base URL
|
||||
private String wsBaseUrl;
|
||||
// Address human readable part prefix
|
||||
private String hrp;
|
||||
|
||||
private BinanceDexEnvironment(String baseUrl, String wsBaseUrl, String hrp) {
|
||||
this.baseUrl = baseUrl;
|
||||
this.wsBaseUrl = wsBaseUrl;
|
||||
this.hrp = hrp;
|
||||
}
|
||||
|
||||
public String getBaseUrl() {
|
||||
return baseUrl;
|
||||
}
|
||||
|
||||
public String getWsBaseUrl() {
|
||||
return wsBaseUrl;
|
||||
}
|
||||
|
||||
public String getHrp() {
|
||||
return hrp;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
package com.tangem.blockchain.binance.client;
|
||||
|
||||
import com.tangem.blockchain.binance.client.domain.Account;
|
||||
import com.tangem.blockchain.binance.client.domain.AccountSequence;
|
||||
import com.tangem.blockchain.binance.client.domain.Infos;
|
||||
import com.tangem.blockchain.binance.client.encoding.Crypto;
|
||||
import com.tangem.blockchain.binance.client.encoding.message.MessageType;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.bitcoinj.core.ECKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Wallet {
|
||||
private final static Map<BinanceDexEnvironment, String> CHAIN_IDS = new HashMap<>();
|
||||
private String privateKey;
|
||||
private String address;
|
||||
private ECKey ecKey;
|
||||
private byte[] addressBytes;
|
||||
private byte[] pubKeyForSign;
|
||||
private Integer accountNumber;
|
||||
private Long sequence = null;
|
||||
private BinanceDexEnvironment env;
|
||||
|
||||
private String chainId;
|
||||
|
||||
public Wallet(String privateKey, BinanceDexEnvironment env) {
|
||||
if (!StringUtils.isEmpty(privateKey)) {
|
||||
this.privateKey = privateKey;
|
||||
this.env = env;
|
||||
this.ecKey = ECKey.fromPrivate(new BigInteger(privateKey, 16));
|
||||
this.address = Crypto.getAddressFromECKey(this.ecKey, env.getHrp());
|
||||
this.addressBytes = Crypto.decodeAddress(this.address);
|
||||
byte[] pubKey = ecKey.getPubKeyPoint().getEncoded(true);
|
||||
byte[] pubKeyPrefix = MessageType.PubKey.getTypePrefixBytes();
|
||||
this.pubKeyForSign = new byte[pubKey.length + pubKeyPrefix.length + 1];
|
||||
System.arraycopy(pubKeyPrefix, 0, this.pubKeyForSign, 0, pubKeyPrefix.length);
|
||||
pubKeyForSign[pubKeyPrefix.length] = (byte) 33;
|
||||
System.arraycopy(pubKey, 0, this.pubKeyForSign, pubKeyPrefix.length + 1, pubKey.length);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Private key cannot be empty.");
|
||||
}
|
||||
}
|
||||
|
||||
public static Wallet createRandomWallet(BinanceDexEnvironment env) throws IOException {
|
||||
return createWalletFromMnemonicCode(Crypto.generateMnemonicCode(), env);
|
||||
}
|
||||
|
||||
public static Wallet createWalletFromMnemonicCode(List<String> words, BinanceDexEnvironment env) throws IOException {
|
||||
String privateKey = Crypto.getPrivateKeyFromMnemonicCode(words);
|
||||
return new Wallet(privateKey, env);
|
||||
}
|
||||
|
||||
public synchronized void initAccount(BinanceDexApiRestClient client) {
|
||||
Account account = client.getAccount(this.address);
|
||||
if (account != null) {
|
||||
this.accountNumber = account.getAccountNumber();
|
||||
this.sequence = account.getSequence();
|
||||
} else {
|
||||
throw new IllegalStateException("Cannot get account information for address " + this.address);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void reloadAccountSequence(BinanceDexApiRestClient client) {
|
||||
AccountSequence accountSequence = client.getAccountSequence(this.address);
|
||||
this.sequence = accountSequence.getSequence();
|
||||
}
|
||||
|
||||
public synchronized void increaseAccountSequence() {
|
||||
if (this.sequence != null)
|
||||
this.sequence++;
|
||||
}
|
||||
|
||||
public synchronized void decreaseAccountSequence() {
|
||||
if (this.sequence != null)
|
||||
this.sequence--;
|
||||
}
|
||||
|
||||
public synchronized long getSequence() {
|
||||
if (sequence == null)
|
||||
throw new IllegalStateException("Account sequence is not initialized.");
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public synchronized void setAccountNumber(Integer accountNumber) {
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
public synchronized void setSequence(Long sequence) {
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
public synchronized void setChainId(String chainId) {
|
||||
this.chainId = chainId;
|
||||
}
|
||||
|
||||
public synchronized void invalidAccountSequence() {
|
||||
this.sequence = null;
|
||||
}
|
||||
|
||||
public synchronized void ensureWalletIsReady(BinanceDexApiRestClient client) {
|
||||
if (accountNumber == null) {
|
||||
initAccount(client);
|
||||
} else if (sequence == null) {
|
||||
reloadAccountSequence(client);
|
||||
}
|
||||
|
||||
if (chainId == null) {
|
||||
chainId = CHAIN_IDS.get(chainId);
|
||||
if (chainId == null) {
|
||||
initChainId(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void initChainId(BinanceDexApiRestClient client) {
|
||||
Infos info = client.getNodeInfo();
|
||||
chainId = info.getNodeInfo().getNetwork();
|
||||
CHAIN_IDS.put(env, chainId);
|
||||
}
|
||||
|
||||
public String getPrivateKey() {
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public ECKey getEcKey() {
|
||||
return ecKey;
|
||||
}
|
||||
|
||||
public byte[] getPubKeyForSign() {
|
||||
return pubKeyForSign;
|
||||
}
|
||||
|
||||
public int getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
|
||||
public String getChainId() {
|
||||
return chainId;
|
||||
}
|
||||
|
||||
public byte[] getAddressBytes() {
|
||||
return addressBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("addressBytes", addressBytes)
|
||||
.append("address", address)
|
||||
.append("ecKey", ecKey)
|
||||
.append("pubKeyForSign", pubKeyForSign)
|
||||
.append("accountNumber", accountNumber)
|
||||
.append("sequence", sequence)
|
||||
.append("chainId", chainId)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Account {
|
||||
@JsonProperty("account_number")
|
||||
private Integer accountNumber;
|
||||
private String address;
|
||||
private List<Balance> balances;
|
||||
@JsonProperty("public_key")
|
||||
private List<Integer> publicKey;
|
||||
private Long sequence;
|
||||
|
||||
public Integer getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
|
||||
public void setAccountNumber(Integer accountNumber) {
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public List<Balance> getBalances() {
|
||||
return balances;
|
||||
}
|
||||
|
||||
public void setBalances(List<Balance> balances) {
|
||||
this.balances = balances;
|
||||
}
|
||||
|
||||
public List<Integer> getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
|
||||
public void setPublicKey(List<Integer> publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public Long getSequence() {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void setSequence(Long sequence) {
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("accountNumber", accountNumber)
|
||||
.append("address", address)
|
||||
.append("balances", balances)
|
||||
.append("publicKey", publicKey)
|
||||
.append("sequence", sequence)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class AccountSequence {
|
||||
private Long sequence;
|
||||
|
||||
public Long getSequence() {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void setSequence(Long sequence) {
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("sequence", sequence)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Balance {
|
||||
private String symbol;
|
||||
private String free;
|
||||
private String locked;
|
||||
private String frozen;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getFree() {
|
||||
return free;
|
||||
}
|
||||
|
||||
public void setFree(String free) {
|
||||
this.free = free;
|
||||
}
|
||||
|
||||
public String getLocked() {
|
||||
return locked;
|
||||
}
|
||||
|
||||
public void setLocked(String locked) {
|
||||
this.locked = locked;
|
||||
}
|
||||
|
||||
public String getFrozen() {
|
||||
return frozen;
|
||||
}
|
||||
|
||||
public void setFrozen(String frozen) {
|
||||
this.frozen = frozen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("symbol", symbol)
|
||||
.append("free", free)
|
||||
.append("locked", locked)
|
||||
.append("frozen", frozen)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
/**
|
||||
* Kline/Candlestick bars for a symbol. Klines are uniquely identified by their open time.
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
|
||||
@JsonPropertyOrder()
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Candlestick {
|
||||
|
||||
private Long openTime;
|
||||
|
||||
private String open;
|
||||
|
||||
private String high;
|
||||
|
||||
private String low;
|
||||
|
||||
private String close;
|
||||
|
||||
private String volume;
|
||||
|
||||
private Long closeTime;
|
||||
|
||||
private String quoteAssetVolume;
|
||||
|
||||
private Long numberOfTrades;
|
||||
|
||||
public Long getOpenTime() {
|
||||
return openTime;
|
||||
}
|
||||
|
||||
public void setOpenTime(Long openTime) {
|
||||
this.openTime = openTime;
|
||||
}
|
||||
|
||||
public String getOpen() {
|
||||
return open;
|
||||
}
|
||||
|
||||
public void setOpen(String open) {
|
||||
this.open = open;
|
||||
}
|
||||
|
||||
public String getHigh() {
|
||||
return high;
|
||||
}
|
||||
|
||||
public void setHigh(String high) {
|
||||
this.high = high;
|
||||
}
|
||||
|
||||
public String getLow() {
|
||||
return low;
|
||||
}
|
||||
|
||||
public void setLow(String low) {
|
||||
this.low = low;
|
||||
}
|
||||
|
||||
public String getClose() {
|
||||
return close;
|
||||
}
|
||||
|
||||
public void setClose(String close) {
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
public String getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume(String volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public Long getCloseTime() {
|
||||
return closeTime;
|
||||
}
|
||||
|
||||
public void setCloseTime(Long closeTime) {
|
||||
this.closeTime = closeTime;
|
||||
}
|
||||
|
||||
public String getQuoteAssetVolume() {
|
||||
return quoteAssetVolume;
|
||||
}
|
||||
|
||||
public void setQuoteAssetVolume(String quoteAssetVolume) {
|
||||
this.quoteAssetVolume = quoteAssetVolume;
|
||||
}
|
||||
|
||||
public Long getNumberOfTrades() {
|
||||
return numberOfTrades;
|
||||
}
|
||||
|
||||
public void setNumberOfTrades(Long numberOfTrades) {
|
||||
this.numberOfTrades = numberOfTrades;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("openTime", openTime)
|
||||
.append("open", open)
|
||||
.append("high", high)
|
||||
.append("low", low)
|
||||
.append("close", close)
|
||||
.append("volume", volume)
|
||||
.append("closeTime", closeTime)
|
||||
.append("quoteAssetVolume", quoteAssetVolume)
|
||||
.append("numberOfTrades", numberOfTrades)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* Kline/Candlestick intervals.
|
||||
* m -> minutes; h -> hours; d -> days; w -> weeks; M -> months
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public enum CandlestickInterval {
|
||||
ONE_MINUTE("1m"),
|
||||
THREE_MINUTES("3m"),
|
||||
FIVE_MINUTES("5m"),
|
||||
FIFTEEN_MINUTES("15m"),
|
||||
HALF_HOURLY("30m"),
|
||||
HOURLY("1h"),
|
||||
TWO_HOURLY("2h"),
|
||||
FOUR_HOURLY("4h"),
|
||||
SIX_HOURLY("6h"),
|
||||
EIGHT_HOURLY("8h"),
|
||||
TWELVE_HOURLY("12h"),
|
||||
DAILY("1d"),
|
||||
THREE_DAILY("3d"),
|
||||
WEEKLY("1w"),
|
||||
MONTHLY("1M");
|
||||
|
||||
private final String intervalId;
|
||||
|
||||
CandlestickInterval(String intervalId) {
|
||||
this.intervalId = intervalId;
|
||||
}
|
||||
|
||||
public String getIntervalId() {
|
||||
return intervalId;
|
||||
}
|
||||
|
||||
public static CandlestickInterval fromIntervalId(String intervalId) {
|
||||
if (intervalId == null) {
|
||||
throw new IllegalArgumentException("Null interval id");
|
||||
}
|
||||
String id = intervalId.toLowerCase();
|
||||
for (CandlestickInterval interval : values()) {
|
||||
if (id.equals(interval.getIntervalId())) {
|
||||
return interval;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown interval id: " + intervalId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Infos {
|
||||
@JsonProperty("node_info")
|
||||
private NodeInfo nodeInfo;
|
||||
@JsonProperty("sync_info")
|
||||
private SyncInfo syncInfo;
|
||||
@JsonProperty("validator_info")
|
||||
private ValidatorInfo validatorInfo;
|
||||
|
||||
public NodeInfo getNodeInfo() {
|
||||
return nodeInfo;
|
||||
}
|
||||
|
||||
public void setNodeInfo(NodeInfo nodeInfo) {
|
||||
this.nodeInfo = nodeInfo;
|
||||
}
|
||||
|
||||
public SyncInfo getSyncInfo() {
|
||||
return syncInfo;
|
||||
}
|
||||
|
||||
public void setSyncInfo(SyncInfo syncInfo) {
|
||||
this.syncInfo = syncInfo;
|
||||
}
|
||||
|
||||
public ValidatorInfo getValidatorInfo() {
|
||||
return validatorInfo;
|
||||
}
|
||||
|
||||
public void setValidatorInfo(ValidatorInfo validatorInfo) {
|
||||
this.validatorInfo = validatorInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("nodeInfo", nodeInfo)
|
||||
.append("syncInfo", syncInfo)
|
||||
.append("validatorInfo", validatorInfo)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Market {
|
||||
public String baseAssetSymbol;
|
||||
public String quoteAssetSymbol;
|
||||
public String price;
|
||||
public String tickSize;
|
||||
public String lotSize;
|
||||
|
||||
@JsonProperty("base_asset_symbol")
|
||||
public String getBaseAssetSymbol() {
|
||||
return baseAssetSymbol;
|
||||
}
|
||||
|
||||
public void setBaseAssetSymbol(String baseAssetSymbol) {
|
||||
this.baseAssetSymbol = baseAssetSymbol;
|
||||
}
|
||||
|
||||
@JsonProperty("quote_asset_symbol")
|
||||
public String getQuoteAssetSymbol() {
|
||||
return quoteAssetSymbol;
|
||||
}
|
||||
|
||||
public void setQuoteAssetSymbol(String quoteAssetSymbol) {
|
||||
this.quoteAssetSymbol = quoteAssetSymbol;
|
||||
}
|
||||
|
||||
@JsonProperty("price")
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
@JsonProperty("tick_size")
|
||||
public String getTickSize() {
|
||||
return tickSize;
|
||||
}
|
||||
|
||||
public void setTickSize(String tickSize) {
|
||||
this.tickSize = tickSize;
|
||||
}
|
||||
|
||||
@JsonProperty("lot_size")
|
||||
public String getLotSize() {
|
||||
return lotSize;
|
||||
}
|
||||
|
||||
public void setLotSize(String lotSize) {
|
||||
this.lotSize = lotSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("baseAssetSymbol", baseAssetSymbol)
|
||||
.append("quoteAssetSymbol", quoteAssetSymbol)
|
||||
.append("price", price)
|
||||
.append("tickSize", tickSize)
|
||||
.append("lotSize", lotSize)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class NodeInfo {
|
||||
private String id;
|
||||
@JsonProperty("listen_addr")
|
||||
private String listenAddr;
|
||||
private String network;
|
||||
private String version;
|
||||
private String channels;
|
||||
private String moniker;
|
||||
private Map<String, Object> other;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getListenAddr() {
|
||||
return listenAddr;
|
||||
}
|
||||
|
||||
public void setListenAddr(String listenAddr) {
|
||||
this.listenAddr = listenAddr;
|
||||
}
|
||||
|
||||
public String getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public void setNetwork(String network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getChannels() {
|
||||
return channels;
|
||||
}
|
||||
|
||||
public void setChannels(String channels) {
|
||||
this.channels = channels;
|
||||
}
|
||||
|
||||
public String getMoniker() {
|
||||
return moniker;
|
||||
}
|
||||
|
||||
public void setMoniker(String moniker) {
|
||||
this.moniker = moniker;
|
||||
}
|
||||
|
||||
public Map<String, Object> getOther() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOther(Map<String, Object> other) {
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("id", id)
|
||||
.append("listenAddr", listenAddr)
|
||||
.append("network", network)
|
||||
.append("version", version)
|
||||
.append("channels", channels)
|
||||
.append("moniker", moniker)
|
||||
.append("other", other)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Order {
|
||||
private String orderId;
|
||||
private String symbol;
|
||||
private String owner;
|
||||
private String price;
|
||||
private String quantity;
|
||||
private String cumulateQuantity;
|
||||
private String fee;
|
||||
private DateTime orderCreateTime;
|
||||
private DateTime transactionTime;
|
||||
private OrderStatus status;
|
||||
private TimeInForce timeInForce;
|
||||
private OrderSide side;
|
||||
private OrderType type;
|
||||
private String tradeId;
|
||||
private String lastExecutedPrice;
|
||||
private String lastExecutedQuantity;
|
||||
private String transactionHash;
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(String quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public String getCumulateQuantity() {
|
||||
return cumulateQuantity;
|
||||
}
|
||||
|
||||
public void setCumulateQuantity(String cumulateQuantity) {
|
||||
this.cumulateQuantity = cumulateQuantity;
|
||||
}
|
||||
|
||||
public String getFee() {
|
||||
return fee;
|
||||
}
|
||||
|
||||
public void setFee(String fee) {
|
||||
this.fee = fee;
|
||||
}
|
||||
|
||||
public DateTime getOrderCreateTime() {
|
||||
return orderCreateTime;
|
||||
}
|
||||
|
||||
public void setOrderCreateTime(DateTime orderCreateTime) {
|
||||
this.orderCreateTime = orderCreateTime;
|
||||
}
|
||||
|
||||
public DateTime getTransactionTime() {
|
||||
return transactionTime;
|
||||
}
|
||||
|
||||
public void setTransactionTime(DateTime transactionTime) {
|
||||
this.transactionTime = transactionTime;
|
||||
}
|
||||
|
||||
public OrderStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(OrderStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public TimeInForce getTimeInForce() {
|
||||
return timeInForce;
|
||||
}
|
||||
|
||||
public void setTimeInForce(TimeInForce timeInForce) {
|
||||
this.timeInForce = timeInForce;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public OrderType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(OrderType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTradeId() {
|
||||
return tradeId;
|
||||
}
|
||||
|
||||
public void setTradeId(String tradeId) {
|
||||
this.tradeId = tradeId;
|
||||
}
|
||||
|
||||
public String getLastExecutedPrice() {
|
||||
return lastExecutedPrice;
|
||||
}
|
||||
|
||||
public void setLastExecutedPrice(String lastExecutedPrice) {
|
||||
this.lastExecutedPrice = lastExecutedPrice;
|
||||
}
|
||||
|
||||
public String getLastExecutedQuantity() {
|
||||
return lastExecutedQuantity;
|
||||
}
|
||||
|
||||
public void setLastExecutedQuantity(String lastExecutedQuantity) {
|
||||
this.lastExecutedQuantity = lastExecutedQuantity;
|
||||
}
|
||||
|
||||
public String getTransactionHash() {
|
||||
return transactionHash;
|
||||
}
|
||||
|
||||
public void setTransactionHash(String transactionHash) {
|
||||
this.transactionHash = transactionHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("orderId", orderId)
|
||||
.append("symbol", symbol)
|
||||
.append("owner", owner)
|
||||
.append("price", price)
|
||||
.append("quantity", quantity)
|
||||
.append("cumulateQuantity", cumulateQuantity)
|
||||
.append("fee", fee)
|
||||
.append("orderCreateTime", orderCreateTime)
|
||||
.append("transactionTime", transactionTime)
|
||||
.append("status", status)
|
||||
.append("timeInForce", timeInForce)
|
||||
.append("side", side)
|
||||
.append("type", type)
|
||||
.append("tradeId", tradeId)
|
||||
.append("lastExecutedPrice", lastExecutedPrice)
|
||||
.append("lastExecutedQuantity", lastExecutedQuantity)
|
||||
.append("transactionHash", transactionHash)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class OrderBook {
|
||||
private List<OrderBookEntry> asks;
|
||||
private List<OrderBookEntry> bids;
|
||||
private long height;
|
||||
|
||||
public List<OrderBookEntry> getAsks() {
|
||||
return asks;
|
||||
}
|
||||
|
||||
public void setAsks(List<OrderBookEntry> asks) {
|
||||
this.asks = asks;
|
||||
}
|
||||
|
||||
public List<OrderBookEntry> getBids() {
|
||||
return bids;
|
||||
}
|
||||
|
||||
public void setBids(List<OrderBookEntry> bids) {
|
||||
this.bids = bids;
|
||||
}
|
||||
|
||||
public long getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(long height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("asks", asks)
|
||||
.append("bids", bids)
|
||||
.append("height", height)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonDeserialize(using = OrderBookEntryDeserializer.class)
|
||||
@JsonSerialize(using = OrderBookEntrySerializer.class)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class OrderBookEntry {
|
||||
private String price;
|
||||
private String quantity;
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(String quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("price", price)
|
||||
.append("quantity", quantity)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OrderBookEntryDeserializer extends JsonDeserializer<OrderBookEntry> {
|
||||
@Override
|
||||
public OrderBookEntry deserialize(JsonParser jp, DeserializationContext ctx) throws IOException {
|
||||
ObjectCodec oc = jp.getCodec();
|
||||
JsonNode node = oc.readTree(jp);
|
||||
final String price = node.get(0).asText();
|
||||
final String qty = node.get(1).asText();
|
||||
|
||||
OrderBookEntry orderBookEntry = new OrderBookEntry();
|
||||
orderBookEntry.setPrice(price);
|
||||
orderBookEntry.setQuantity(qty);
|
||||
return orderBookEntry;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class OrderBookEntrySerializer extends JsonSerializer<OrderBookEntry> {
|
||||
@Override
|
||||
public void serialize(OrderBookEntry orderBookEntry, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||
gen.writeStartArray();
|
||||
gen.writeString(orderBookEntry.getPrice());
|
||||
gen.writeString(orderBookEntry.getQuantity());
|
||||
gen.writeEndArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class OrderList {
|
||||
private List<Order> order;
|
||||
private Long total;
|
||||
|
||||
public List<Order> getOrder() {
|
||||
return order;
|
||||
}
|
||||
|
||||
public void setOrder(List<Order> order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
public Long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("order", order)
|
||||
.append("total", total)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum OrderSide {
|
||||
BUY(1L), SELL(2L);
|
||||
|
||||
private long value;
|
||||
|
||||
OrderSide(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static OrderSide fromValue(long value) {
|
||||
for (OrderSide os : OrderSide.values()) {
|
||||
if (os.value == value) {
|
||||
return os;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public long toValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
public enum OrderStatus {
|
||||
Ack,
|
||||
PartialFill,
|
||||
IocNoFill,
|
||||
FullyFill,
|
||||
Canceled,
|
||||
Expired,
|
||||
Unknown
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum OrderType {
|
||||
LIMIT(2L);
|
||||
|
||||
private long value;
|
||||
|
||||
OrderType(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static OrderType fromValue(long value) {
|
||||
for (OrderType ot : OrderType.values()) {
|
||||
if (ot.value == value) {
|
||||
return ot;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public long toValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Peer {
|
||||
private Boolean accelerated;
|
||||
@JsonProperty("access_addr")
|
||||
private String accessAddress;
|
||||
private List<String> capabilities;
|
||||
private String id;
|
||||
@JsonProperty("listen_addr")
|
||||
private String listenAddress;
|
||||
private String moniker;
|
||||
private String network;
|
||||
@JsonProperty("stream_addr")
|
||||
private String streamAddress;
|
||||
private String version;
|
||||
|
||||
public Boolean getAccelerated() {
|
||||
return accelerated;
|
||||
}
|
||||
|
||||
public void setAccelerated(Boolean accelerated) {
|
||||
this.accelerated = accelerated;
|
||||
}
|
||||
|
||||
public String getAccessAddress() {
|
||||
return accessAddress;
|
||||
}
|
||||
|
||||
public void setAccessAddress(String accessAddress) {
|
||||
this.accessAddress = accessAddress;
|
||||
}
|
||||
|
||||
public List<String> getCapabilities() {
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
public void setCapabilities(List<String> capabilities) {
|
||||
this.capabilities = capabilities;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getListenAddress() {
|
||||
return listenAddress;
|
||||
}
|
||||
|
||||
public void setListenAddress(String listenAddress) {
|
||||
this.listenAddress = listenAddress;
|
||||
}
|
||||
|
||||
public String getMoniker() {
|
||||
return moniker;
|
||||
}
|
||||
|
||||
public void setMoniker(String moniker) {
|
||||
this.moniker = moniker;
|
||||
}
|
||||
|
||||
public String getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public void setNetwork(String network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
public String getStreamAddress() {
|
||||
return streamAddress;
|
||||
}
|
||||
|
||||
public void setStreamAddress(String streamAddress) {
|
||||
this.streamAddress = streamAddress;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("accelerated", accelerated)
|
||||
.append("accessAddress", accessAddress)
|
||||
.append("capabilities", capabilities)
|
||||
.append("id", id)
|
||||
.append("listenAddress", listenAddress)
|
||||
.append("moniker", moniker)
|
||||
.append("network", network)
|
||||
.append("streamAddress", streamAddress)
|
||||
.append("version", version)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class SyncInfo {
|
||||
@JsonProperty("latest_block_hash")
|
||||
private String latestBlockHash;
|
||||
@JsonProperty("latest_app_hash")
|
||||
private String latestAppHash;
|
||||
@JsonProperty("latest_block_height")
|
||||
private Long latestBlockHeight;
|
||||
@JsonProperty("latest_block_time")
|
||||
private DateTime latestBlockTime;
|
||||
@JsonProperty("catching_up")
|
||||
private Boolean catchingUp;
|
||||
|
||||
public String getLatestBlockHash() {
|
||||
return latestBlockHash;
|
||||
}
|
||||
|
||||
public void setLatestBlockHash(String latestBlockHash) {
|
||||
this.latestBlockHash = latestBlockHash;
|
||||
}
|
||||
|
||||
public String getLatestAppHash() {
|
||||
return latestAppHash;
|
||||
}
|
||||
|
||||
public void setLatestAppHash(String latestAppHash) {
|
||||
this.latestAppHash = latestAppHash;
|
||||
}
|
||||
|
||||
public Long getLatestBlockHeight() {
|
||||
return latestBlockHeight;
|
||||
}
|
||||
|
||||
public void setLatestBlockHeight(Long latestBlockHeight) {
|
||||
this.latestBlockHeight = latestBlockHeight;
|
||||
}
|
||||
|
||||
public DateTime getLatestBlockTime() {
|
||||
return latestBlockTime;
|
||||
}
|
||||
|
||||
public void setLatestBlockTime(DateTime latestBlockTime) {
|
||||
this.latestBlockTime = latestBlockTime;
|
||||
}
|
||||
|
||||
public Boolean getCatchingUp() {
|
||||
return catchingUp;
|
||||
}
|
||||
|
||||
public void setCatchingUp(Boolean catchingUp) {
|
||||
this.catchingUp = catchingUp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("latestBlockHash", latestBlockHash)
|
||||
.append("latestAppHash", latestAppHash)
|
||||
.append("latestBlockHeight", latestBlockHeight)
|
||||
.append("latestBlockTime", latestBlockTime)
|
||||
.append("catchingUp", catchingUp)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TickerStatistics {
|
||||
private String symbol;
|
||||
private String priceChange;
|
||||
private String priceChangePercent;
|
||||
private String prevClosePrice;
|
||||
private String lastPrice;
|
||||
private String lastQuantity;
|
||||
private String openPrice;
|
||||
private String highPrice;
|
||||
private String lowPrice;
|
||||
private Long openTime;
|
||||
private Long closeTime;
|
||||
private String firstId;
|
||||
private String lastId;
|
||||
private String bidPrice;
|
||||
private String bidQuantity;
|
||||
private String askPrice;
|
||||
private String askQuantity;
|
||||
private String weightedAvgPrice;
|
||||
private String volume;
|
||||
private String quoteVolume;
|
||||
private Long count;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getPriceChange() {
|
||||
return priceChange;
|
||||
}
|
||||
|
||||
public void setPriceChange(String priceChange) {
|
||||
this.priceChange = priceChange;
|
||||
}
|
||||
|
||||
public String getPriceChangePercent() {
|
||||
return priceChangePercent;
|
||||
}
|
||||
|
||||
public void setPriceChangePercent(String priceChangePercent) {
|
||||
this.priceChangePercent = priceChangePercent;
|
||||
}
|
||||
|
||||
public String getPrevClosePrice() {
|
||||
return prevClosePrice;
|
||||
}
|
||||
|
||||
public void setPrevClosePrice(String prevClosePrice) {
|
||||
this.prevClosePrice = prevClosePrice;
|
||||
}
|
||||
|
||||
public String getLastPrice() {
|
||||
return lastPrice;
|
||||
}
|
||||
|
||||
public void setLastPrice(String lastPrice) {
|
||||
this.lastPrice = lastPrice;
|
||||
}
|
||||
|
||||
public String getLastQuantity() {
|
||||
return lastQuantity;
|
||||
}
|
||||
|
||||
public void setLastQuantity(String lastQuantity) {
|
||||
this.lastQuantity = lastQuantity;
|
||||
}
|
||||
|
||||
public String getOpenPrice() {
|
||||
return openPrice;
|
||||
}
|
||||
|
||||
public void setOpenPrice(String openPrice) {
|
||||
this.openPrice = openPrice;
|
||||
}
|
||||
|
||||
public String getHighPrice() {
|
||||
return highPrice;
|
||||
}
|
||||
|
||||
public void setHighPrice(String highPrice) {
|
||||
this.highPrice = highPrice;
|
||||
}
|
||||
|
||||
public String getLowPrice() {
|
||||
return lowPrice;
|
||||
}
|
||||
|
||||
public void setLowPrice(String lowPrice) {
|
||||
this.lowPrice = lowPrice;
|
||||
}
|
||||
|
||||
public Long getOpenTime() {
|
||||
return openTime;
|
||||
}
|
||||
|
||||
public void setOpenTime(Long openTime) {
|
||||
this.openTime = openTime;
|
||||
}
|
||||
|
||||
public Long getCloseTime() {
|
||||
return closeTime;
|
||||
}
|
||||
|
||||
public void setCloseTime(Long closeTime) {
|
||||
this.closeTime = closeTime;
|
||||
}
|
||||
|
||||
public String getFirstId() {
|
||||
return firstId;
|
||||
}
|
||||
|
||||
public void setFirstId(String firstId) {
|
||||
this.firstId = firstId;
|
||||
}
|
||||
|
||||
public String getLastId() {
|
||||
return lastId;
|
||||
}
|
||||
|
||||
public void setLastId(String lastId) {
|
||||
this.lastId = lastId;
|
||||
}
|
||||
|
||||
public String getBidPrice() {
|
||||
return bidPrice;
|
||||
}
|
||||
|
||||
public void setBidPrice(String bidPrice) {
|
||||
this.bidPrice = bidPrice;
|
||||
}
|
||||
|
||||
public String getBidQuantity() {
|
||||
return bidQuantity;
|
||||
}
|
||||
|
||||
public void setBidQuantity(String bidQuantity) {
|
||||
this.bidQuantity = bidQuantity;
|
||||
}
|
||||
|
||||
public String getAskPrice() {
|
||||
return askPrice;
|
||||
}
|
||||
|
||||
public void setAskPrice(String askPrice) {
|
||||
this.askPrice = askPrice;
|
||||
}
|
||||
|
||||
public String getAskQuantity() {
|
||||
return askQuantity;
|
||||
}
|
||||
|
||||
public void setAskQuantity(String askQuantity) {
|
||||
this.askQuantity = askQuantity;
|
||||
}
|
||||
|
||||
public String getWeightedAvgPrice() {
|
||||
return weightedAvgPrice;
|
||||
}
|
||||
|
||||
public void setWeightedAvgPrice(String weightedAvgPrice) {
|
||||
this.weightedAvgPrice = weightedAvgPrice;
|
||||
}
|
||||
|
||||
public String getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public void setVolume(String volume) {
|
||||
this.volume = volume;
|
||||
}
|
||||
|
||||
public String getQuoteVolume() {
|
||||
return quoteVolume;
|
||||
}
|
||||
|
||||
public void setQuoteVolume(String quoteVolume) {
|
||||
this.quoteVolume = quoteVolume;
|
||||
}
|
||||
|
||||
public Long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public void setCount(Long count) {
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("symbol", symbol)
|
||||
.append("priceChange", priceChange)
|
||||
.append("priceChangePercent", priceChangePercent)
|
||||
.append("prevClosePrice", prevClosePrice)
|
||||
.append("lastPrice", lastPrice)
|
||||
.append("lastQuantity", lastQuantity)
|
||||
.append("openPrice", openPrice)
|
||||
.append("highPrice", highPrice)
|
||||
.append("lowPrice", lowPrice)
|
||||
.append("openTime", openTime)
|
||||
.append("closeTime", closeTime)
|
||||
.append("firstId", firstId)
|
||||
.append("lastId", lastId)
|
||||
.append("bidPrice", bidPrice)
|
||||
.append("bidQuantity", bidQuantity)
|
||||
.append("askPrice", askPrice)
|
||||
.append("askQuantity", askQuantity)
|
||||
.append("weightedAvgPrice", weightedAvgPrice)
|
||||
.append("volume", volume)
|
||||
.append("quoteVolume", quoteVolume)
|
||||
.append("count", count)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Time {
|
||||
@JsonProperty("ap_time")
|
||||
private DateTime apTime;
|
||||
@JsonProperty("block_time")
|
||||
private DateTime blockTime;
|
||||
|
||||
public DateTime getApTime() {
|
||||
return apTime;
|
||||
}
|
||||
|
||||
public void setApTime(DateTime apTime) {
|
||||
this.apTime = apTime;
|
||||
}
|
||||
|
||||
public DateTime getBlockTime() {
|
||||
return blockTime;
|
||||
}
|
||||
|
||||
public void setBlockTime(DateTime blockTime) {
|
||||
this.blockTime = blockTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("apTime", apTime)
|
||||
.append("blockTime", blockTime)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
public enum TimeInForce {
|
||||
GTE(1L), IOC(3L);
|
||||
|
||||
private long value;
|
||||
|
||||
TimeInForce(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@JsonCreator
|
||||
public static TimeInForce fromValue(long value) {
|
||||
for (TimeInForce tif : TimeInForce.values()) {
|
||||
if (tif.value == value) {
|
||||
return tif;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@JsonValue
|
||||
public long toValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Token {
|
||||
private String name;
|
||||
private String symbol;
|
||||
@JsonProperty("original_symbol")
|
||||
private String originalSymbol;
|
||||
@JsonProperty("total_supply")
|
||||
private String totalSupply;
|
||||
private String owner;
|
||||
private boolean mintable;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getOriginalSymbol() {
|
||||
return originalSymbol;
|
||||
}
|
||||
|
||||
public void setOriginalSymbol(String originalSymbol) {
|
||||
this.originalSymbol = originalSymbol;
|
||||
}
|
||||
|
||||
public String getTotalSupply() {
|
||||
return totalSupply;
|
||||
}
|
||||
|
||||
public void setTotalSupply(String totalSupply) {
|
||||
this.totalSupply = totalSupply;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public boolean isMintable() {
|
||||
return mintable;
|
||||
}
|
||||
|
||||
public void setMintable(boolean mintable) {
|
||||
this.mintable = mintable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("name", name)
|
||||
.append("symbol", symbol)
|
||||
.append("originalSymbol", originalSymbol)
|
||||
.append("totalSupply", totalSupply)
|
||||
.append("owner", owner)
|
||||
.append("mintable", mintable)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Trade {
|
||||
private String baseAsset;
|
||||
private Long blockHeight;
|
||||
private String buyFee;
|
||||
private String buyerId;
|
||||
private String buyerOrderId;
|
||||
private String price;
|
||||
private String quantity;
|
||||
private String quoteAsset;
|
||||
private String sellFee;
|
||||
private String sellerId;
|
||||
private String sellerOrderId;
|
||||
private String symbol;
|
||||
private Long time;
|
||||
private String tradeId;
|
||||
|
||||
public String getBaseAsset() {
|
||||
return baseAsset;
|
||||
}
|
||||
|
||||
public void setBaseAsset(String baseAsset) {
|
||||
this.baseAsset = baseAsset;
|
||||
}
|
||||
|
||||
public Long getBlockHeight() {
|
||||
return blockHeight;
|
||||
}
|
||||
|
||||
public void setBlockHeight(Long blockHeight) {
|
||||
this.blockHeight = blockHeight;
|
||||
}
|
||||
|
||||
public String getBuyFee() {
|
||||
return buyFee;
|
||||
}
|
||||
|
||||
public void setBuyFee(String buyFee) {
|
||||
this.buyFee = buyFee;
|
||||
}
|
||||
|
||||
public String getBuyerId() {
|
||||
return buyerId;
|
||||
}
|
||||
|
||||
public void setBuyerId(String buyerId) {
|
||||
this.buyerId = buyerId;
|
||||
}
|
||||
|
||||
public String getBuyerOrderId() {
|
||||
return buyerOrderId;
|
||||
}
|
||||
|
||||
public void setBuyerOrderId(String buyerOrderId) {
|
||||
this.buyerOrderId = buyerOrderId;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(String quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public String getQuoteAsset() {
|
||||
return quoteAsset;
|
||||
}
|
||||
|
||||
public void setQuoteAsset(String quoteAsset) {
|
||||
this.quoteAsset = quoteAsset;
|
||||
}
|
||||
|
||||
public String getSellFee() {
|
||||
return sellFee;
|
||||
}
|
||||
|
||||
public void setSellFee(String sellFee) {
|
||||
this.sellFee = sellFee;
|
||||
}
|
||||
|
||||
public String getSellerId() {
|
||||
return sellerId;
|
||||
}
|
||||
|
||||
public void setSellerId(String sellerId) {
|
||||
this.sellerId = sellerId;
|
||||
}
|
||||
|
||||
public String getSellerOrderId() {
|
||||
return sellerOrderId;
|
||||
}
|
||||
|
||||
public void setSellerOrderId(String sellerOrderId) {
|
||||
this.sellerOrderId = sellerOrderId;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(Long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getTradeId() {
|
||||
return tradeId;
|
||||
}
|
||||
|
||||
public void setTradeId(String tradeId) {
|
||||
this.tradeId = tradeId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("baseAsset", baseAsset)
|
||||
.append("blockHeight", blockHeight)
|
||||
.append("buyFee", buyFee)
|
||||
.append("buyerId", buyerId)
|
||||
.append("buyerOrderId", buyerOrderId)
|
||||
.append("price", price)
|
||||
.append("quantity", quantity)
|
||||
.append("quoteAsset", quoteAsset)
|
||||
.append("sellFee", sellFee)
|
||||
.append("sellerId", sellerId)
|
||||
.append("sellerOrderId", sellerOrderId)
|
||||
.append("symbol", symbol)
|
||||
.append("time", time)
|
||||
.append("tradeId", tradeId)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TradePage {
|
||||
private Long total;
|
||||
private List<Trade> trade;
|
||||
|
||||
public Long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List<Trade> getTrade() {
|
||||
return trade;
|
||||
}
|
||||
|
||||
public void setTrade(List<Trade> trade) {
|
||||
this.trade = trade;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("total", total)
|
||||
.append("trade", trade)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TradeStatistics {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Transaction {
|
||||
private Long blockHeight;
|
||||
private Integer code;
|
||||
private Long confirmBlocks;
|
||||
private String data;
|
||||
private String fromAddr;
|
||||
private String orderId;
|
||||
private String timeStamp;
|
||||
private String toAddr;
|
||||
private Long txAge;
|
||||
private String txAsset;
|
||||
private String txFee;
|
||||
private String txHash;
|
||||
private String txType;
|
||||
private String value;
|
||||
|
||||
public Long getBlockHeight() {
|
||||
return blockHeight;
|
||||
}
|
||||
|
||||
public void setBlockHeight(Long blockHeight) {
|
||||
this.blockHeight = blockHeight;
|
||||
}
|
||||
|
||||
public Integer getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(Integer code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Long getConfirmBlocks() {
|
||||
return confirmBlocks;
|
||||
}
|
||||
|
||||
public void setConfirmBlocks(Long confirmBlocks) {
|
||||
this.confirmBlocks = confirmBlocks;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getFromAddr() {
|
||||
return fromAddr;
|
||||
}
|
||||
|
||||
public void setFromAddr(String fromAddr) {
|
||||
this.fromAddr = fromAddr;
|
||||
}
|
||||
|
||||
public String getOrderId() {
|
||||
return orderId;
|
||||
}
|
||||
|
||||
public void setOrderId(String orderId) {
|
||||
this.orderId = orderId;
|
||||
}
|
||||
|
||||
public String getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
public void setTimeStamp(String timeStamp) {
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
public String getToAddr() {
|
||||
return toAddr;
|
||||
}
|
||||
|
||||
public void setToAddr(String toAddr) {
|
||||
this.toAddr = toAddr;
|
||||
}
|
||||
|
||||
public Long getTxAge() {
|
||||
return txAge;
|
||||
}
|
||||
|
||||
public void setTxAge(Long txAge) {
|
||||
this.txAge = txAge;
|
||||
}
|
||||
|
||||
public String getTxAsset() {
|
||||
return txAsset;
|
||||
}
|
||||
|
||||
public void setTxAsset(String txAsset) {
|
||||
this.txAsset = txAsset;
|
||||
}
|
||||
|
||||
public String getTxFee() {
|
||||
return txFee;
|
||||
}
|
||||
|
||||
public void setTxFee(String txFee) {
|
||||
this.txFee = txFee;
|
||||
}
|
||||
|
||||
public String getTxHash() {
|
||||
return txHash;
|
||||
}
|
||||
|
||||
public void setTxHash(String txHash) {
|
||||
this.txHash = txHash;
|
||||
}
|
||||
|
||||
public String getTxType() {
|
||||
return txType;
|
||||
}
|
||||
|
||||
public void setTxType(String txType) {
|
||||
this.txType = txType;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("blockHeight", blockHeight)
|
||||
.append("code", code)
|
||||
.append("confirmBlocks", confirmBlocks)
|
||||
.append("data", data)
|
||||
.append("fromAddr", fromAddr)
|
||||
.append("orderId", orderId)
|
||||
.append("timeStamp", timeStamp)
|
||||
.append("toAddr", toAddr)
|
||||
.append("txAge", txAge)
|
||||
.append("txAsset", txAsset)
|
||||
.append("txFee", txFee)
|
||||
.append("txHash", txHash)
|
||||
.append("txType", txType)
|
||||
.append("value", value)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransactionMetadata {
|
||||
private int code;
|
||||
private String data;
|
||||
private String hash;
|
||||
private String log;
|
||||
private boolean ok;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public String getLog() {
|
||||
return log;
|
||||
}
|
||||
|
||||
public boolean isOk() {
|
||||
return ok;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||
.append("code", code)
|
||||
.append("data", data)
|
||||
.append("hash", hash)
|
||||
.append("log", log)
|
||||
.append("ok", ok)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class TransactionPage {
|
||||
private Long total;
|
||||
private List<Transaction> tx;
|
||||
|
||||
public Long getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public List<Transaction> getTx() {
|
||||
return tx;
|
||||
}
|
||||
|
||||
public void setTx(List<Transaction> tx) {
|
||||
this.tx = tx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("total", total)
|
||||
.append("tx", tx)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
public enum TransactionType {
|
||||
NEW_ORDER,
|
||||
ISSUE_TOKEN,
|
||||
BURN_TOKEN,
|
||||
LIST_TOKEN,
|
||||
CANCEL_ORDER,
|
||||
FREEZE_TOKEN,
|
||||
UN_FREEZE_TOKEN,
|
||||
TRANSFER,
|
||||
PROPOSAL,
|
||||
VOTE;
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class ValidatorInfo {
|
||||
private String address;
|
||||
@JsonProperty("pub_key")
|
||||
private List<Integer> pubKey;
|
||||
@JsonProperty("voting_power")
|
||||
private Long votingPower;
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public List<Integer> getPubKey() {
|
||||
return pubKey;
|
||||
}
|
||||
|
||||
public void setPubKey(List<Integer> pubKey) {
|
||||
this.pubKey = pubKey;
|
||||
}
|
||||
|
||||
public Long getVotingPower() {
|
||||
return votingPower;
|
||||
}
|
||||
|
||||
public void setVotingPower(Long votingPower) {
|
||||
this.votingPower = votingPower;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("address", address)
|
||||
.append("pubKey", pubKey)
|
||||
.append("votingPower", votingPower)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.blockchain.binance.client.domain;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Validators {
|
||||
@JsonProperty("block_height")
|
||||
private Long blockHeight;
|
||||
private List<ValidatorInfo> validators;
|
||||
|
||||
public Long getBlockHeight() {
|
||||
return blockHeight;
|
||||
}
|
||||
|
||||
public void setBlockHeight(Long blockHeight) {
|
||||
this.blockHeight = blockHeight;
|
||||
}
|
||||
|
||||
public List<ValidatorInfo> getValidators() {
|
||||
return validators;
|
||||
}
|
||||
|
||||
public void setValidators(List<ValidatorInfo> validators) {
|
||||
this.validators = validators;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("blockHeight", blockHeight)
|
||||
.append("validators", validators)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.blockchain.binance.client.domain.broadcast;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class CancelOrder {
|
||||
private String symbol;
|
||||
@JsonProperty("refid")
|
||||
private String refId;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getRefId() {
|
||||
return refId;
|
||||
}
|
||||
|
||||
public void setRefId(String refId) {
|
||||
this.refId = refId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("symbol", symbol)
|
||||
.append("refId", refId)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package com.tangem.blockchain.binance.client.domain.broadcast;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderSide;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderType;
|
||||
import com.tangem.blockchain.binance.client.domain.TimeInForce;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class NewOrder {
|
||||
private String symbol;
|
||||
private OrderType orderType;
|
||||
private OrderSide side;
|
||||
private String price;
|
||||
private String quantity;
|
||||
private TimeInForce timeInForce;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public OrderType getOrderType() {
|
||||
return orderType;
|
||||
}
|
||||
|
||||
public void setOrderType(OrderType orderType) {
|
||||
this.orderType = orderType;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(String price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public String getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(String quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public TimeInForce getTimeInForce() {
|
||||
return timeInForce;
|
||||
}
|
||||
|
||||
public void setTimeInForce(TimeInForce timeInForce) {
|
||||
this.timeInForce = timeInForce;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("symbol", symbol)
|
||||
.append("orderType", orderType)
|
||||
.append("side", side)
|
||||
.append("price", price)
|
||||
.append("quantity", quantity)
|
||||
.append("timeInForce", timeInForce)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.blockchain.binance.client.domain.broadcast;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class TokenFreeze {
|
||||
private String symbol;
|
||||
private String amount;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(String amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("symbol", symbol)
|
||||
.append("amount", amount)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.blockchain.binance.client.domain.broadcast;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class TokenUnfreeze {
|
||||
private String symbol;
|
||||
private String amount;
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(String amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("symbol", symbol)
|
||||
.append("amount", amount)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package com.tangem.blockchain.binance.client.domain.broadcast;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Optional fields for Bianace DEX standard transaction
|
||||
*/
|
||||
public class TransactionOption {
|
||||
|
||||
public static final TransactionOption DEFAULT_INSTANCE =
|
||||
new TransactionOption("", BinanceDexConstants.BINANCE_DEX_API_CLIENT_JAVA_SOURCE, null);
|
||||
|
||||
private String memo;
|
||||
private long source;
|
||||
private byte[] data;
|
||||
|
||||
public TransactionOption(String memo, long source, byte[] data) {
|
||||
this.memo = memo;
|
||||
this.source = source;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getMemo() {
|
||||
return memo;
|
||||
}
|
||||
|
||||
public void setMemo(String memo) {
|
||||
this.memo = memo;
|
||||
}
|
||||
|
||||
public long getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(long source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("memo", memo)
|
||||
.append("source", source)
|
||||
.append("data", data)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.tangem.blockchain.binance.client.domain.broadcast;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class Transfer {
|
||||
private String fromAddress;
|
||||
private String toAddress;
|
||||
private String coin;
|
||||
private String amount;
|
||||
|
||||
public String getFromAddress() {
|
||||
return fromAddress;
|
||||
}
|
||||
|
||||
public void setFromAddress(String fromAddress) {
|
||||
this.fromAddress = fromAddress;
|
||||
}
|
||||
|
||||
public String getToAddress() {
|
||||
return toAddress;
|
||||
}
|
||||
|
||||
public void setToAddress(String toAddress) {
|
||||
this.toAddress = toAddress;
|
||||
}
|
||||
|
||||
public String getCoin() {
|
||||
return coin;
|
||||
}
|
||||
|
||||
public void setCoin(String coin) {
|
||||
this.coin = coin;
|
||||
}
|
||||
|
||||
public String getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(String amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("fromAddress", fromAddress)
|
||||
.append("toAddress", toAddress)
|
||||
.append("coin", coin)
|
||||
.append("amount", amount)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
package com.tangem.blockchain.binance.client.domain.request;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderSide;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderStatus;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClosedOrdersRequest {
|
||||
private String address;
|
||||
private Long end;
|
||||
private Integer limit;
|
||||
private Integer offset;
|
||||
private OrderSide side;
|
||||
private Long start;
|
||||
private List<OrderStatus> status;
|
||||
private String symbol;
|
||||
private Integer total;
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Long getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(Long end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(Integer limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(Integer offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public Long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Long start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public List<OrderStatus> getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(List<OrderStatus> status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Integer getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Integer total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("address", address)
|
||||
.append("end", end)
|
||||
.append("limit", limit)
|
||||
.append("offset", offset)
|
||||
.append("side", side)
|
||||
.append("start", start)
|
||||
.append("status", status)
|
||||
.append("symbol", symbol)
|
||||
.append("total", total)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.tangem.blockchain.binance.client.domain.request;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class OpenOrdersRequest {
|
||||
private String address;
|
||||
private Integer limit;
|
||||
private Integer offset;
|
||||
private String symbol;
|
||||
private Integer total;
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(Integer limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(Integer offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Integer getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Integer total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("address", address)
|
||||
.append("limit", limit)
|
||||
.append("offset", offset)
|
||||
.append("symbol", symbol)
|
||||
.append("total", total)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package com.tangem.blockchain.binance.client.domain.request;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderSide;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class TradesRequest {
|
||||
private String address;
|
||||
private String buyerOrderId;
|
||||
private Long end;
|
||||
private Long height;
|
||||
private Integer limit;
|
||||
private Integer offset;
|
||||
private String quoteAsset;
|
||||
private String sellerOrderId;
|
||||
private OrderSide side;
|
||||
private Long start;
|
||||
private String symbol;
|
||||
private Integer total;
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getBuyerOrderId() {
|
||||
return buyerOrderId;
|
||||
}
|
||||
|
||||
public void setBuyerOrderId(String buyerOrderId) {
|
||||
this.buyerOrderId = buyerOrderId;
|
||||
}
|
||||
|
||||
public Long getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public void setEnd(Long end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public Long getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(Long height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(Integer limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(Integer offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public String getQuoteAsset() {
|
||||
return quoteAsset;
|
||||
}
|
||||
|
||||
public void setQuoteAsset(String quoteAsset) {
|
||||
this.quoteAsset = quoteAsset;
|
||||
}
|
||||
|
||||
public String getSellerOrderId() {
|
||||
return sellerOrderId;
|
||||
}
|
||||
|
||||
public void setSellerOrderId(String sellerOrderId) {
|
||||
this.sellerOrderId = sellerOrderId;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public Long getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Long start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public Integer getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setTotal(Integer total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("address", address)
|
||||
.append("buyerOrderId", buyerOrderId)
|
||||
.append("end", end)
|
||||
.append("height", height)
|
||||
.append("limit", limit)
|
||||
.append("offset", offset)
|
||||
.append("quoteAsset", quoteAsset)
|
||||
.append("sellerOrderId", sellerOrderId)
|
||||
.append("side", side)
|
||||
.append("start", start)
|
||||
.append("symbol", symbol)
|
||||
.append("total", total)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package com.tangem.blockchain.binance.client.domain.request;
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderSide;
|
||||
import com.tangem.blockchain.binance.client.domain.TransactionType;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
public class TransactionsRequest {
|
||||
private String address;
|
||||
private Long blockHeight;
|
||||
private Long endTime;
|
||||
private Integer limit;
|
||||
private Integer offset;
|
||||
private OrderSide side;
|
||||
private Long startTime;
|
||||
private String txAsset;
|
||||
private TransactionType txType;
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Long getBlockHeight() {
|
||||
return blockHeight;
|
||||
}
|
||||
|
||||
public void setBlockHeight(Long blockHeight) {
|
||||
this.blockHeight = blockHeight;
|
||||
}
|
||||
|
||||
public Long getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public void setEndTime(Long endTime) {
|
||||
this.endTime = endTime;
|
||||
}
|
||||
|
||||
public Integer getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setLimit(Integer limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public Integer getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public void setOffset(Integer offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public Long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(Long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public String getTxAsset() {
|
||||
return txAsset;
|
||||
}
|
||||
|
||||
public void setTxAsset(String txAsset) {
|
||||
this.txAsset = txAsset;
|
||||
}
|
||||
|
||||
public TransactionType getTxType() {
|
||||
return txType;
|
||||
}
|
||||
|
||||
public void setTxType(TransactionType txType) {
|
||||
this.txType = txType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("address", address)
|
||||
.append("blockHeight", blockHeight)
|
||||
.append("endTime", endTime)
|
||||
.append("limit", limit)
|
||||
.append("offset", offset)
|
||||
.append("side", side)
|
||||
.append("startTime", startTime)
|
||||
.append("txAsset", txAsset)
|
||||
.append("txType", txType)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
* Copyright 2015 Andreas Schildbach
|
||||
*
|
||||
* 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.blockchain.binance.client.encoding;
|
||||
|
||||
import org.bitcoinj.core.Base58;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
// TODO: Copied from https://github.com/bitcoinj/bitcoinj. Remove these files after they are included in a new bitconj release
|
||||
public class AddressFormatException extends IllegalArgumentException {
|
||||
public AddressFormatException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AddressFormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* This exception is thrown by {@link Base58}, {@link Bech32} and the {@link PrefixedChecksummedBytes} hierarchy of
|
||||
* classes when you try to decode data and a character isn't valid. You shouldn't allow the user to proceed in this
|
||||
* case.
|
||||
*/
|
||||
public static class InvalidCharacter extends AddressFormatException {
|
||||
public final char character;
|
||||
public final int position;
|
||||
|
||||
public InvalidCharacter(char character, int position) {
|
||||
super("Invalid character '" + Character.toString(character) + "' at position " + position);
|
||||
this.character = character;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This exception is thrown by {@link Base58}, {@link Bech32} and the {@link PrefixedChecksummedBytes} hierarchy of
|
||||
* classes when you try to decode data and the data isn't of the right size. You shouldn't allow the user to proceed
|
||||
* in this case.
|
||||
*/
|
||||
public static class InvalidDataLength extends AddressFormatException {
|
||||
public InvalidDataLength() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidDataLength(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This exception is thrown by {@link Base58}, {@link Bech32} and the {@link PrefixedChecksummedBytes} hierarchy of
|
||||
* classes when you try to decode data and the checksum isn't valid. You shouldn't allow the user to proceed in this
|
||||
* case.
|
||||
*/
|
||||
public static class InvalidChecksum extends AddressFormatException {
|
||||
public InvalidChecksum() {
|
||||
super("Checksum does not validate");
|
||||
}
|
||||
|
||||
public InvalidChecksum(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This exception is thrown by the {@link PrefixedChecksummedBytes} hierarchy of classes when you try and decode an
|
||||
* address or private key with an invalid prefix (version header or human-readable part). You shouldn't allow the
|
||||
* user to proceed in this case.
|
||||
*/
|
||||
public static class InvalidPrefix extends AddressFormatException {
|
||||
public InvalidPrefix() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidPrefix(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This exception is thrown by the {@link PrefixedChecksummedBytes} hierarchy of classes when you try and decode an
|
||||
* address with a prefix (version header or human-readable part) that used by another network (usually: mainnet vs
|
||||
* testnet). You shouldn't allow the user to proceed in this case as they are trying to send money across different
|
||||
* chains, an operation that is guaranteed to destroy the money.
|
||||
*/
|
||||
public static class WrongNetwork extends InvalidPrefix {
|
||||
public WrongNetwork(int versionHeader) {
|
||||
super("Version code of address did not match acceptable versions for network: " + versionHeader);
|
||||
}
|
||||
|
||||
public WrongNetwork(String hrp) {
|
||||
super("Human readable part of address did not match acceptable HRPs for network: " + hrp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright 2018 Coinomi Ltd
|
||||
*
|
||||
* 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.blockchain.binance.client.encoding;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
// TODO: Copied from https://github.com/bitcoinj/bitcoinj. Remove these files after they are included in a new bitconj release
|
||||
public class Bech32 {
|
||||
/**
|
||||
* The io.nayuki.bitcoin.crypto.Bech32 character set for encoding.
|
||||
*/
|
||||
private static final String CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
||||
|
||||
/**
|
||||
* The io.nayuki.bitcoin.crypto.Bech32 character set for decoding.
|
||||
*/
|
||||
private static final byte[] CHARSET_REV = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
public static class Bech32Data {
|
||||
final String hrp;
|
||||
final byte[] data;
|
||||
|
||||
private Bech32Data(final String hrp, final byte[] data) {
|
||||
this.hrp = hrp;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getHrp() {
|
||||
return hrp;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the polynomial with value coefficients mod the generator as 30-bit.
|
||||
*/
|
||||
private static int polymod(final byte[] values) {
|
||||
int c = 1;
|
||||
for (byte v_i : values) {
|
||||
int c0 = (c >>> 25) & 0xff;
|
||||
c = ((c & 0x1ffffff) << 5) ^ (v_i & 0xff);
|
||||
if ((c0 & 1) != 0) c ^= 0x3b6a57b2;
|
||||
if ((c0 & 2) != 0) c ^= 0x26508e6d;
|
||||
if ((c0 & 4) != 0) c ^= 0x1ea119fa;
|
||||
if ((c0 & 8) != 0) c ^= 0x3d4233dd;
|
||||
if ((c0 & 16) != 0) c ^= 0x2a1462b3;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand a HRP for use in checksum computation.
|
||||
*/
|
||||
private static byte[] expandHrp(final String hrp) {
|
||||
int hrpLength = hrp.length();
|
||||
byte ret[] = new byte[hrpLength * 2 + 1];
|
||||
for (int i = 0; i < hrpLength; ++i) {
|
||||
int c = hrp.charAt(i) & 0x7f; // Limit to standard 7-bit ASCII
|
||||
ret[i] = (byte) ((c >>> 5) & 0x07);
|
||||
ret[i + hrpLength + 1] = (byte) (c & 0x1f);
|
||||
}
|
||||
ret[hrpLength] = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a checksum.
|
||||
*/
|
||||
private static boolean verifyChecksum(final String hrp, final byte[] values) {
|
||||
byte[] hrpExpanded = expandHrp(hrp);
|
||||
byte[] combined = new byte[hrpExpanded.length + values.length];
|
||||
System.arraycopy(hrpExpanded, 0, combined, 0, hrpExpanded.length);
|
||||
System.arraycopy(values, 0, combined, hrpExpanded.length, values.length);
|
||||
return polymod(combined) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a checksum.
|
||||
*/
|
||||
private static byte[] createChecksum(final String hrp, final byte[] values) {
|
||||
byte[] hrpExpanded = expandHrp(hrp);
|
||||
byte[] enc = new byte[hrpExpanded.length + values.length + 6];
|
||||
System.arraycopy(hrpExpanded, 0, enc, 0, hrpExpanded.length);
|
||||
System.arraycopy(values, 0, enc, hrpExpanded.length, values.length);
|
||||
int mod = polymod(enc) ^ 1;
|
||||
byte[] ret = new byte[6];
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
ret[i] = (byte) ((mod >>> (5 * (5 - i))) & 31);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a io.nayuki.bitcoin.crypto.Bech32 string.
|
||||
*/
|
||||
public static String encode(final Bech32Data bech32) {
|
||||
return encode(bech32.hrp, bech32.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a io.nayuki.bitcoin.crypto.Bech32 string.
|
||||
*/
|
||||
public static String encode(String hrp, final byte[] values) {
|
||||
checkArgument(hrp.length() >= 1, "Human-readable part is too short");
|
||||
checkArgument(hrp.length() <= 83, "Human-readable part is too long");
|
||||
hrp = hrp.toLowerCase(Locale.ROOT);
|
||||
byte[] checksum = createChecksum(hrp, values);
|
||||
byte[] combined = new byte[values.length + checksum.length];
|
||||
System.arraycopy(values, 0, combined, 0, values.length);
|
||||
System.arraycopy(checksum, 0, combined, values.length, checksum.length);
|
||||
StringBuilder sb = new StringBuilder(hrp.length() + 1 + combined.length);
|
||||
sb.append(hrp);
|
||||
sb.append('1');
|
||||
for (byte b : combined) {
|
||||
sb.append(CHARSET.charAt(b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a io.nayuki.bitcoin.crypto.Bech32 string.
|
||||
*/
|
||||
public static Bech32Data decode(final String str) throws AddressFormatException {
|
||||
boolean lower = false, upper = false;
|
||||
if (str.length() < 8)
|
||||
throw new AddressFormatException.InvalidDataLength("Input too short: " + str.length());
|
||||
if (str.length() > 90)
|
||||
throw new AddressFormatException.InvalidDataLength("Input too long: " + str.length());
|
||||
for (int i = 0; i < str.length(); ++i) {
|
||||
char c = str.charAt(i);
|
||||
if (c < 33 || c > 126) throw new AddressFormatException.InvalidCharacter(c, i);
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
if (upper)
|
||||
throw new AddressFormatException.InvalidCharacter(c, i);
|
||||
lower = true;
|
||||
}
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
if (lower)
|
||||
throw new AddressFormatException.InvalidCharacter(c, i);
|
||||
upper = true;
|
||||
}
|
||||
}
|
||||
final int pos = str.lastIndexOf('1');
|
||||
if (pos < 1) throw new AddressFormatException.InvalidPrefix("Missing human-readable part");
|
||||
final int dataPartLength = str.length() - 1 - pos;
|
||||
if (dataPartLength < 6)
|
||||
throw new AddressFormatException.InvalidDataLength("Data part too short: " + dataPartLength);
|
||||
byte[] values = new byte[dataPartLength];
|
||||
for (int i = 0; i < dataPartLength; ++i) {
|
||||
char c = str.charAt(i + pos + 1);
|
||||
if (CHARSET_REV[c] == -1) throw new AddressFormatException.InvalidCharacter(c, i + pos + 1);
|
||||
values[i] = CHARSET_REV[c];
|
||||
}
|
||||
String hrp = str.substring(0, pos).toLowerCase(Locale.ROOT);
|
||||
if (!verifyChecksum(hrp, values)) throw new AddressFormatException.InvalidChecksum();
|
||||
return new Bech32Data(hrp, Arrays.copyOfRange(values, 0, values.length - 6));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
package com.tangem.blockchain.binance.client.encoding;
|
||||
|
||||
import org.bitcoinj.core.ECKey;
|
||||
import org.bitcoinj.core.Sha256Hash;
|
||||
import org.bitcoinj.core.Utils;
|
||||
import org.bitcoinj.crypto.ChildNumber;
|
||||
import org.bitcoinj.crypto.DeterministicKey;
|
||||
import org.bitcoinj.crypto.HDKeyDerivation;
|
||||
import org.bitcoinj.crypto.HDUtils;
|
||||
import org.bitcoinj.crypto.MnemonicCode;
|
||||
import org.bitcoinj.crypto.MnemonicException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.List;
|
||||
|
||||
public class Crypto {
|
||||
|
||||
private static final String HD_PATH = "44H/714H/0H/0/0";
|
||||
|
||||
public static byte[] sign(byte[] msg, String privateKey) throws NoSuchAlgorithmException {
|
||||
ECKey k = ECKey.fromPrivate(new BigInteger(privateKey, 16));
|
||||
|
||||
return sign(msg, k);
|
||||
}
|
||||
|
||||
public static byte[] sign(byte[] msg, ECKey k) throws NoSuchAlgorithmException {
|
||||
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] msgHash = digest.digest(msg);
|
||||
|
||||
ECKey.ECDSASignature signature = k.sign(Sha256Hash.wrap(msgHash));
|
||||
|
||||
byte[] result = new byte[64];
|
||||
System.arraycopy(Utils.bigIntegerToBytes(signature.r, 32), 0, result, 0, 32);
|
||||
System.arraycopy(Utils.bigIntegerToBytes(signature.s, 32), 0, result, 32, 32);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] decodeAddress(String address) throws SegwitAddressException {
|
||||
byte[] dec = Bech32.decode(address).getData();
|
||||
return convertBits(dec, 0, dec.length, 5, 8, false);
|
||||
}
|
||||
|
||||
public static String getAddressFromPrivateKey(String privateKey, String hrp) {
|
||||
ECKey ecKey = ECKey.fromPrivate(new BigInteger(privateKey, 16));
|
||||
return getAddressFromECKey(ecKey, hrp);
|
||||
}
|
||||
|
||||
public static String getAddressFromECKey(ECKey ecKey, String hrp) {
|
||||
byte[] hash = ecKey.getPubKeyHash();
|
||||
return Bech32.encode(hrp, convertBits(hash, 0, hash.length, 8, 5, false));
|
||||
}
|
||||
|
||||
public static String getPrivateKeyFromMnemonicCode(List<String> words) {
|
||||
byte[] seed = MnemonicCode.INSTANCE.toSeed(words, "");
|
||||
DeterministicKey key = HDKeyDerivation.createMasterPrivateKey(seed);
|
||||
|
||||
List<ChildNumber> childNumbers = HDUtils.parsePath(HD_PATH);
|
||||
for (ChildNumber cn : childNumbers) {
|
||||
key = HDKeyDerivation.deriveChildKey(key, cn);
|
||||
}
|
||||
return key.getPrivateKeyAsHex();
|
||||
}
|
||||
|
||||
public static List<String> generateMnemonicCode() {
|
||||
byte[] entrophy = new byte[256 / 8];
|
||||
new SecureRandom().nextBytes(entrophy);
|
||||
try {
|
||||
return MnemonicCode.INSTANCE.toMnemonic(entrophy);
|
||||
} catch (MnemonicException.MnemonicLengthException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SegwitAddressException extends IllegalArgumentException {
|
||||
SegwitAddressException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
SegwitAddressException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* see https://github.com/sipa/bech32/pull/40/files
|
||||
*/
|
||||
public static byte[] convertBits(final byte[] in, final int inStart, final int inLen,
|
||||
final int fromBits, final int toBits, final boolean pad)
|
||||
throws SegwitAddressException {
|
||||
int acc = 0;
|
||||
int bits = 0;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(64);
|
||||
final int maxv = (1 << toBits) - 1;
|
||||
final int max_acc = (1 << (fromBits + toBits - 1)) - 1;
|
||||
for (int i = 0; i < inLen; i++) {
|
||||
int value = in[i + inStart] & 0xff;
|
||||
if ((value >>> fromBits) != 0) {
|
||||
throw new SegwitAddressException(String.format(
|
||||
"Input value '%X' exceeds '%d' bit size", value, fromBits));
|
||||
}
|
||||
acc = ((acc << fromBits) | value) & max_acc;
|
||||
bits += fromBits;
|
||||
while (bits >= toBits) {
|
||||
bits -= toBits;
|
||||
out.write((acc >>> bits) & maxv);
|
||||
}
|
||||
}
|
||||
if (pad) {
|
||||
if (bits > 0) out.write((acc << (toBits - bits)) & maxv);
|
||||
} else if (bits >= fromBits || ((acc << (toBits - bits)) & maxv) != 0) {
|
||||
throw new SegwitAddressException("Could not convert bits, invalid padding");
|
||||
}
|
||||
return out.toByteArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package com.tangem.blockchain.binance.client.encoding;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class EncodeUtils {
|
||||
private static final ObjectWriter OBJECT_WRITER;
|
||||
|
||||
static {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
OBJECT_WRITER = mapper.writer();
|
||||
}
|
||||
|
||||
public static byte[] hexStringToByteArray(String s) {
|
||||
return Hex.decode(s);
|
||||
}
|
||||
|
||||
public static String bytesToHex(byte[] bytes) {
|
||||
return Hex.toHexString(bytes);
|
||||
}
|
||||
|
||||
public static String toJsonStringSortKeys(Object object) throws JsonProcessingException {
|
||||
return OBJECT_WRITER.writeValueAsString(object);
|
||||
}
|
||||
|
||||
public static byte[] toJsonEncodeBytes(Object object) throws JsonProcessingException {
|
||||
return toJsonStringSortKeys(object).getBytes(Charset.forName("UTF-8"));
|
||||
}
|
||||
|
||||
public static byte[] aminoWrap(byte[] raw, byte[] typePrefix, boolean isPrefixLength) throws IOException {
|
||||
int totalLen = raw.length + typePrefix.length;
|
||||
if (isPrefixLength)
|
||||
totalLen += CodedOutputStream.computeUInt64SizeNoTag(totalLen);
|
||||
|
||||
byte[] msg = new byte[totalLen];
|
||||
CodedOutputStream cos = CodedOutputStream.newInstance(msg);
|
||||
if (isPrefixLength)
|
||||
cos.writeUInt64NoTag(raw.length + typePrefix.length);
|
||||
cos.write(typePrefix, 0, typePrefix.length);
|
||||
cos.write(raw, 0, raw.length);
|
||||
cos.flush();
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
public interface BinanceDexTransactionMessage {
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class CancelOrderMessage implements BinanceDexTransactionMessage {
|
||||
private String sender;
|
||||
private String symbol;
|
||||
@JsonProperty("refid")
|
||||
private String refId;
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(String sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public String getRefId() {
|
||||
return refId;
|
||||
}
|
||||
|
||||
public void setRefId(String refId) {
|
||||
this.refId = refId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("sender", sender)
|
||||
.append("symbol", symbol)
|
||||
.append("refId", refId)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class InputOutput {
|
||||
private String address;
|
||||
private List<Token> coins;
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public List<Token> getCoins() {
|
||||
return coins;
|
||||
}
|
||||
|
||||
public void setCoins(List<Token> coins) {
|
||||
this.coins = coins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("address", address)
|
||||
.append("coins", coins)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.tangem.blockchain.binance.client.encoding.EncodeUtils;
|
||||
|
||||
/**
|
||||
* Binance dex standard transactiont types.
|
||||
*/
|
||||
public enum MessageType {
|
||||
Send("2A2C87FA"),
|
||||
NewOrder("CE6DC043"),
|
||||
CancelOrder("166E681B"),
|
||||
TokenFreeze("E774B32D"),
|
||||
TokenUnfreeze("6515FF0D"),
|
||||
StdSignature(null),
|
||||
PubKey("EB5AE987"),
|
||||
StdTx("F0625DEE");
|
||||
|
||||
private byte[] typePrefixBytes;
|
||||
|
||||
MessageType(String typePrefix) {
|
||||
if (typePrefix == null) {
|
||||
this.typePrefixBytes = new byte[0];
|
||||
} else
|
||||
this.typePrefixBytes = EncodeUtils.hexStringToByteArray(typePrefix);
|
||||
}
|
||||
|
||||
public byte[] getTypePrefixBytes() {
|
||||
return typePrefixBytes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderSide;
|
||||
import com.tangem.blockchain.binance.client.domain.OrderType;
|
||||
import com.tangem.blockchain.binance.client.domain.TimeInForce;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class NewOrderMessage implements BinanceDexTransactionMessage {
|
||||
private String id;
|
||||
@JsonProperty("ordertype")
|
||||
private OrderType orderType;
|
||||
private long price;
|
||||
private long quantity;
|
||||
private String sender;
|
||||
private OrderSide side;
|
||||
private String symbol;
|
||||
@JsonProperty("timeinforce")
|
||||
private TimeInForce timeInForce;
|
||||
|
||||
private NewOrderMessage() {
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public void setSender(String sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public OrderType getOrderType() {
|
||||
return orderType;
|
||||
}
|
||||
|
||||
public void setOrderType(OrderType orderType) {
|
||||
this.orderType = orderType;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public void setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
public long getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public void setPrice(long price) {
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
public long getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public void setQuantity(long quantity) {
|
||||
this.quantity = quantity;
|
||||
}
|
||||
|
||||
public TimeInForce getTimeInForce() {
|
||||
return timeInForce;
|
||||
}
|
||||
|
||||
public void setTimeInForce(TimeInForce timeInForce) {
|
||||
this.timeInForce = timeInForce;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||
.append("sender", sender)
|
||||
.append("id", id)
|
||||
.append("symbol", symbol)
|
||||
.append("orderType", orderType)
|
||||
.append("side", side)
|
||||
.append("price", price)
|
||||
.append("quantity", quantity)
|
||||
.append("timeInForce", timeInForce)
|
||||
.toString();
|
||||
}
|
||||
|
||||
public static NewOrderBuilder newBuilder() {
|
||||
return new NewOrderBuilder();
|
||||
}
|
||||
|
||||
public NewOrderBuilder toBuilder() {
|
||||
return newBuilder()
|
||||
.setSender(this.sender)
|
||||
.setId(this.id)
|
||||
.setSymbol(this.symbol)
|
||||
.setOrderType(this.orderType)
|
||||
.setSide(this.side)
|
||||
.setPrice(TransactionRequestAssembler.longToDouble(this.price))
|
||||
.setQuantity(TransactionRequestAssembler.longToDouble(this.quantity))
|
||||
.setTimeInForce(this.timeInForce);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder class for NewOrderMessage transaction. It handles price/quantity conversion from double to long.
|
||||
*/
|
||||
public static class NewOrderBuilder {
|
||||
private String id;
|
||||
private OrderType orderType;
|
||||
private String price;
|
||||
private String quantity;
|
||||
private String sender;
|
||||
private OrderSide side;
|
||||
private String symbol;
|
||||
private TimeInForce timeInForce;
|
||||
|
||||
public NewOrderMessage build() {
|
||||
NewOrderMessage newOrder = new NewOrderMessage();
|
||||
newOrder.setId(id);
|
||||
newOrder.setOrderType(orderType);
|
||||
newOrder.setPrice(TransactionRequestAssembler.doubleToLong(price));
|
||||
newOrder.setQuantity(TransactionRequestAssembler.doubleToLong(quantity));
|
||||
newOrder.setSender(sender);
|
||||
newOrder.setSide(side);
|
||||
newOrder.setSymbol(symbol);
|
||||
newOrder.setTimeInForce(timeInForce);
|
||||
return newOrder;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setId(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OrderType getOrderType() {
|
||||
return orderType;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setOrderType(OrderType orderType) {
|
||||
this.orderType = orderType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setPrice(String price) {
|
||||
this.price = price;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getQuantity() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setQuantity(String quantity) {
|
||||
this.quantity = quantity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setSender(String sender) {
|
||||
this.sender = sender;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OrderSide getSide() {
|
||||
return side;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setSide(OrderSide side) {
|
||||
this.side = side;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TimeInForce getTimeInForce() {
|
||||
return timeInForce;
|
||||
}
|
||||
|
||||
public NewOrderBuilder setTimeInForce(TimeInForce timeInForce) {
|
||||
this.timeInForce = timeInForce;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class SignData {
|
||||
@JsonProperty("chain_id")
|
||||
private String chainId;
|
||||
@JsonProperty("account_number")
|
||||
private String accountNumber;
|
||||
private String sequence;
|
||||
private String memo;
|
||||
private BinanceDexTransactionMessage[] msgs;
|
||||
private String source;
|
||||
private byte[] data;
|
||||
|
||||
public String getChainId() {
|
||||
return chainId;
|
||||
}
|
||||
|
||||
public void setChainId(String chainId) {
|
||||
this.chainId = chainId;
|
||||
}
|
||||
|
||||
public String getAccountNumber() {
|
||||
return accountNumber;
|
||||
}
|
||||
|
||||
public void setAccountNumber(String accountNumber) {
|
||||
this.accountNumber = accountNumber;
|
||||
}
|
||||
|
||||
public String getSequence() {
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void setSequence(String sequence) {
|
||||
this.sequence = sequence;
|
||||
}
|
||||
|
||||
public String getMemo() {
|
||||
return memo;
|
||||
}
|
||||
|
||||
public void setMemo(String memo) {
|
||||
this.memo = memo;
|
||||
}
|
||||
|
||||
public BinanceDexTransactionMessage[] getMsgs() {
|
||||
return msgs;
|
||||
}
|
||||
|
||||
public void setMsgs(BinanceDexTransactionMessage[] msgs) {
|
||||
this.msgs = msgs;
|
||||
}
|
||||
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public void setSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
|
||||
.append("chainId", chainId)
|
||||
.append("accountNumber", accountNumber)
|
||||
.append("sequence", sequence)
|
||||
.append("memo", memo)
|
||||
.append("msgs", msgs)
|
||||
.append("source", source)
|
||||
.append("data", data)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class Token {
|
||||
private String denom;
|
||||
private Long amount;
|
||||
|
||||
public String getDenom() {
|
||||
return denom;
|
||||
}
|
||||
|
||||
public void setDenom(String denom) {
|
||||
this.denom = denom;
|
||||
}
|
||||
|
||||
public Long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("denom", denom)
|
||||
.append("amount", amount)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class TokenFreezeMessage implements BinanceDexTransactionMessage {
|
||||
private String from;
|
||||
private String symbol;
|
||||
private long amount;
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("from", from)
|
||||
.append("symbol", symbol)
|
||||
.append("amount", amount)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class TokenUnfreezeMessage implements BinanceDexTransactionMessage {
|
||||
private String from;
|
||||
private String symbol;
|
||||
|
||||
private long amount;
|
||||
|
||||
public String getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
public void setFrom(String from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
public String getSymbol() {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public void setSymbol(String symbol) {
|
||||
this.symbol = symbol;
|
||||
}
|
||||
|
||||
public long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("from", from)
|
||||
.append("symbol", symbol)
|
||||
.append("amount", amount)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.tangem.blockchain.binance.client.Wallet;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TokenFreeze;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TokenUnfreeze;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TransactionOption;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.Transfer;
|
||||
import com.tangem.blockchain.binance.client.encoding.Crypto;
|
||||
import com.tangem.blockchain.binance.client.encoding.EncodeUtils;
|
||||
import com.tangem.blockchain.binance.proto.StdSignature;
|
||||
import com.tangem.blockchain.binance.proto.StdTx;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
/**
|
||||
* Assemble a transaction message body.
|
||||
* https://testnet-dex.binance.org/doc/encoding.html
|
||||
*/
|
||||
public class TransactionRequestAssembler {
|
||||
private static final okhttp3.MediaType MEDIA_TYPE = okhttp3.MediaType.parse("text/plain; charset=utf-8");
|
||||
private static final BigDecimal MULTIPLY_FACTOR = BigDecimal.valueOf(1e8);
|
||||
private static final BigDecimal MAX_NUMBER = new BigDecimal(Long.MAX_VALUE);
|
||||
|
||||
private Wallet wallet;
|
||||
private TransactionOption options;
|
||||
|
||||
public TransactionRequestAssembler(Wallet wallet, TransactionOption options) {
|
||||
this.wallet = wallet;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public static long doubleToLong(String d) {
|
||||
BigDecimal encodeValue = new BigDecimal(d).multiply(MULTIPLY_FACTOR);
|
||||
if (encodeValue.compareTo(MAX_NUMBER) > 0) {
|
||||
throw new IllegalArgumentException(d + " is too large.");
|
||||
}
|
||||
return encodeValue.longValue();
|
||||
|
||||
}
|
||||
|
||||
public static String longToDouble(long l) {
|
||||
return BigDecimal.valueOf(l).divide(MULTIPLY_FACTOR).toString();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] sign(BinanceDexTransactionMessage msg)
|
||||
throws JsonProcessingException, NoSuchAlgorithmException {
|
||||
SignData sd = new SignData();
|
||||
sd.setChainId(wallet.getChainId());
|
||||
sd.setAccountNumber(String.valueOf(wallet.getAccountNumber()));
|
||||
sd.setSequence(String.valueOf(wallet.getSequence()));
|
||||
sd.setMsgs(new BinanceDexTransactionMessage[]{msg});
|
||||
|
||||
sd.setMemo(options.getMemo());
|
||||
sd.setSource(String.valueOf(options.getSource()));
|
||||
sd.setData(options.getData());
|
||||
return Crypto.sign(EncodeUtils.toJsonEncodeBytes(sd), wallet.getEcKey());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeSignature(byte[] signatureBytes) throws IOException {
|
||||
StdSignature stdSignature = StdSignature.newBuilder().setPubKey(ByteString.copyFrom(wallet.getPubKeyForSign()))
|
||||
.setSignature(ByteString.copyFrom(signatureBytes))
|
||||
.setAccountNumber(wallet.getAccountNumber())
|
||||
.setSequence(wallet.getSequence())
|
||||
.build();
|
||||
|
||||
return EncodeUtils.aminoWrap(
|
||||
stdSignature.toByteArray(), MessageType.StdSignature.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeStdTx(byte[] msg, byte[] signature) throws IOException {
|
||||
StdTx.Builder stdTxBuilder = StdTx.newBuilder()
|
||||
.addMsgs(ByteString.copyFrom(msg))
|
||||
.addSignatures(ByteString.copyFrom(signature))
|
||||
.setMemo(options.getMemo())
|
||||
.setSource(options.getSource());
|
||||
if (options.getData() != null) {
|
||||
stdTxBuilder = stdTxBuilder.setData(ByteString.copyFrom(options.getData()));
|
||||
}
|
||||
StdTx stdTx = stdTxBuilder.build();
|
||||
return EncodeUtils.aminoWrap(stdTx.toByteArray(), MessageType.StdTx.getTypePrefixBytes(), true);
|
||||
}
|
||||
|
||||
private RequestBody createRequestBody(byte[] stdTx) {
|
||||
return RequestBody.create(MEDIA_TYPE, EncodeUtils.bytesToHex(stdTx));
|
||||
}
|
||||
|
||||
private String generateOrderId() {
|
||||
return EncodeUtils.bytesToHex(wallet.getAddressBytes()).toUpperCase() + "-" + (wallet.getSequence() + 1);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
NewOrderMessage createNewOrderMessage(
|
||||
com.tangem.blockchain.binance.client.domain.broadcast.NewOrder newOrder) {
|
||||
return NewOrderMessage.newBuilder()
|
||||
.setId(generateOrderId())
|
||||
.setOrderType(newOrder.getOrderType())
|
||||
.setPrice(newOrder.getPrice())
|
||||
.setQuantity(newOrder.getQuantity())
|
||||
.setSender(wallet.getAddress())
|
||||
.setSide(newOrder.getSide())
|
||||
.setSymbol(newOrder.getSymbol())
|
||||
.setTimeInForce(newOrder.getTimeInForce())
|
||||
.build();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeNewOrderMessage(NewOrderMessage newOrder)
|
||||
throws IOException {
|
||||
com.tangem.blockchain.binance.proto.NewOrder proto = com.tangem.blockchain.binance.proto.NewOrder.newBuilder()
|
||||
.setSender(ByteString.copyFrom(wallet.getAddressBytes()))
|
||||
.setId(newOrder.getId())
|
||||
.setSymbol(newOrder.getSymbol())
|
||||
.setOrdertype(newOrder.getOrderType().toValue())
|
||||
.setSide(newOrder.getSide().toValue())
|
||||
.setPrice(newOrder.getPrice())
|
||||
.setQuantity(newOrder.getQuantity())
|
||||
.setTimeinforce(newOrder.getTimeInForce().toValue())
|
||||
.build();
|
||||
return EncodeUtils.aminoWrap(proto.toByteArray(), MessageType.NewOrder.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public RequestBody buildNewOrder(com.tangem.blockchain.binance.client.domain.broadcast.NewOrder newOrder)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
NewOrderMessage msgBean = createNewOrderMessage(newOrder);
|
||||
byte[] msg = encodeNewOrderMessage(msgBean);
|
||||
byte[] signature = encodeSignature(sign(msgBean));
|
||||
byte[] stdTx = encodeStdTx(msg, signature);
|
||||
return createRequestBody(stdTx);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
CancelOrderMessage createCancelOrderMessage(
|
||||
com.tangem.blockchain.binance.client.domain.broadcast.CancelOrder cancelOrder) {
|
||||
CancelOrderMessage bean =
|
||||
new CancelOrderMessage();
|
||||
bean.setRefId(cancelOrder.getRefId());
|
||||
bean.setSymbol(cancelOrder.getSymbol());
|
||||
bean.setSender(wallet.getAddress());
|
||||
return bean;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeCancelOrderMessage(CancelOrderMessage cancelOrder)
|
||||
throws IOException {
|
||||
com.tangem.blockchain.binance.proto.CancelOrder proto = com.tangem.blockchain.binance.proto.CancelOrder.newBuilder()
|
||||
.setSender(ByteString.copyFrom(wallet.getAddressBytes()))
|
||||
.setSymbol(cancelOrder.getSymbol())
|
||||
.setRefid(cancelOrder.getRefId())
|
||||
.build();
|
||||
return EncodeUtils.aminoWrap(proto.toByteArray(), MessageType.CancelOrder.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public RequestBody buildCancelOrder(com.tangem.blockchain.binance.client.domain.broadcast.CancelOrder cancelOrder)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
CancelOrderMessage msgBean = createCancelOrderMessage(cancelOrder);
|
||||
byte[] msg = encodeCancelOrderMessage(msgBean);
|
||||
byte[] signature = encodeSignature(sign(msgBean));
|
||||
byte[] stdTx = encodeStdTx(msg, signature);
|
||||
return createRequestBody(stdTx);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
TransferMessage createTransferMessage(Transfer transfer) {
|
||||
Token token = new Token();
|
||||
token.setDenom(transfer.getCoin());
|
||||
token.setAmount(doubleToLong(transfer.getAmount()));
|
||||
List<Token> coins = Collections.singletonList(token);
|
||||
|
||||
InputOutput input = new InputOutput();
|
||||
input.setAddress(transfer.getFromAddress());
|
||||
input.setCoins(coins);
|
||||
InputOutput output = new InputOutput();
|
||||
output.setAddress(transfer.getToAddress());
|
||||
output.setCoins(coins);
|
||||
|
||||
TransferMessage msgBean = new TransferMessage();
|
||||
msgBean.setInputs(Collections.singletonList(input));
|
||||
msgBean.setOutputs(Collections.singletonList(output));
|
||||
return msgBean;
|
||||
}
|
||||
|
||||
private com.tangem.blockchain.binance.proto.Send.Input toProtoInput(InputOutput input) {
|
||||
byte[] address = Crypto.decodeAddress(input.getAddress());
|
||||
com.tangem.blockchain.binance.proto.Send.Input.Builder builder =
|
||||
com.tangem.blockchain.binance.proto.Send.Input.newBuilder().setAddress(ByteString.copyFrom(address));
|
||||
|
||||
for (Token coin : input.getCoins()) {
|
||||
com.tangem.blockchain.binance.proto.Send.Token protCoin =
|
||||
com.tangem.blockchain.binance.proto.Send.Token.newBuilder().setAmount(coin.getAmount())
|
||||
.setDenom(coin.getDenom()).build();
|
||||
builder.addCoins(protCoin);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private com.tangem.blockchain.binance.proto.Send.Output toProtoOutput(InputOutput output) {
|
||||
byte[] address = Crypto.decodeAddress(output.getAddress());
|
||||
com.tangem.blockchain.binance.proto.Send.Output.Builder builder =
|
||||
com.tangem.blockchain.binance.proto.Send.Output.newBuilder().setAddress(ByteString.copyFrom(address));
|
||||
|
||||
for (Token coin : output.getCoins()) {
|
||||
com.tangem.blockchain.binance.proto.Send.Token protCoin =
|
||||
com.tangem.blockchain.binance.proto.Send.Token.newBuilder().setAmount(coin.getAmount())
|
||||
.setDenom(coin.getDenom()).build();
|
||||
builder.addCoins(protCoin);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeTransferMessage(TransferMessage msg)
|
||||
throws IOException {
|
||||
com.tangem.blockchain.binance.proto.Send.Builder builder = com.tangem.blockchain.binance.proto.Send.newBuilder();
|
||||
for (InputOutput input : msg.getInputs()) {
|
||||
builder.addInputs(toProtoInput(input));
|
||||
}
|
||||
for (InputOutput output : msg.getOutputs()) {
|
||||
builder.addOutputs(toProtoOutput(output));
|
||||
}
|
||||
com.tangem.blockchain.binance.proto.Send proto = builder.build();
|
||||
return EncodeUtils.aminoWrap(proto.toByteArray(), MessageType.Send.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public RequestBody buildTransfer(Transfer transfer)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
TransferMessage msgBean = createTransferMessage(transfer);
|
||||
byte[] msg = encodeTransferMessage(msgBean);
|
||||
byte[] signature = encodeSignature(sign(msgBean));
|
||||
byte[] stdTx = encodeStdTx(msg, signature);
|
||||
return createRequestBody(stdTx);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
TokenFreezeMessage createTokenFreezeMessage(TokenFreeze freeze) {
|
||||
TokenFreezeMessage msg = new TokenFreezeMessage();
|
||||
msg.setAmount(doubleToLong(freeze.getAmount()));
|
||||
msg.setFrom(wallet.getAddress());
|
||||
msg.setSymbol(freeze.getSymbol());
|
||||
return msg;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeTokenFreezeMessage(TokenFreezeMessage freeze) throws IOException {
|
||||
byte[] address = Crypto.decodeAddress(freeze.getFrom());
|
||||
com.tangem.blockchain.binance.proto.TokenFreeze proto =
|
||||
com.tangem.blockchain.binance.proto.TokenFreeze.newBuilder().setFrom(ByteString.copyFrom(address))
|
||||
.setAmount(freeze.getAmount())
|
||||
.setSymbol(freeze.getSymbol())
|
||||
.build();
|
||||
return EncodeUtils.aminoWrap(proto.toByteArray(), MessageType.TokenFreeze.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public RequestBody buildTokenFreeze(TokenFreeze freeze)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
TokenFreezeMessage msgBean = createTokenFreezeMessage(freeze);
|
||||
byte[] msg = encodeTokenFreezeMessage(msgBean);
|
||||
byte[] signature = encodeSignature(sign(msgBean));
|
||||
byte[] stdTx = encodeStdTx(msg, signature);
|
||||
return createRequestBody(stdTx);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
TokenUnfreezeMessage createTokenUnfreezeMessage(TokenUnfreeze unfreeze) {
|
||||
TokenUnfreezeMessage msg = new TokenUnfreezeMessage();
|
||||
msg.setAmount(doubleToLong(unfreeze.getAmount()));
|
||||
msg.setFrom(wallet.getAddress());
|
||||
msg.setSymbol(unfreeze.getSymbol());
|
||||
return msg;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
byte[] encodeTokenUnfreezeMessage(TokenUnfreezeMessage unfreeze) throws IOException {
|
||||
byte[] address = Crypto.decodeAddress(unfreeze.getFrom());
|
||||
com.tangem.blockchain.binance.proto.TokenUnfreeze proto =
|
||||
com.tangem.blockchain.binance.proto.TokenUnfreeze.newBuilder().setFrom(ByteString.copyFrom(address))
|
||||
.setAmount(unfreeze.getAmount())
|
||||
.setSymbol(unfreeze.getSymbol())
|
||||
.build();
|
||||
return EncodeUtils.aminoWrap(proto.toByteArray(), MessageType.TokenUnfreeze.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public RequestBody buildTokenUnfreeze(TokenUnfreeze unfreeze)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
TokenUnfreezeMessage msgBean = createTokenUnfreezeMessage(unfreeze);
|
||||
byte[] msg = encodeTokenUnfreezeMessage(msgBean);
|
||||
byte[] signature = encodeSignature(sign(msgBean));
|
||||
byte[] stdTx = encodeStdTx(msg, signature);
|
||||
return createRequestBody(stdTx);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.tangem.blockchain.binance.BinanceAccountData;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.TransactionOption;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.Transfer;
|
||||
import com.tangem.blockchain.binance.client.encoding.Crypto;
|
||||
import com.tangem.blockchain.binance.client.encoding.EncodeUtils;
|
||||
import com.tangem.blockchain.binance.proto.StdSignature;
|
||||
import com.tangem.blockchain.binance.proto.StdTx;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
/**
|
||||
* Assemble a transaction message body with external signature
|
||||
* https://testnet-dex.binance.org/doc/encoding.html
|
||||
*/
|
||||
public class TransactionRequestAssemblerExtSign {
|
||||
private static final okhttp3.MediaType MEDIA_TYPE = okhttp3.MediaType.parse("text/plain; charset=utf-8");
|
||||
private static final BigDecimal MULTIPLY_FACTOR = BigDecimal.valueOf(1e8);
|
||||
private static final BigDecimal MAX_NUMBER = new BigDecimal(Long.MAX_VALUE);
|
||||
|
||||
//private Wallet wallet;
|
||||
private BinanceAccountData binanceAccountData;
|
||||
private byte[] pubKeyForSign;
|
||||
private TransactionOption options;
|
||||
|
||||
public TransactionRequestAssemblerExtSign(BinanceAccountData binanceAccountData, byte[] pubKeyForSign, TransactionOption options) {
|
||||
this.binanceAccountData = binanceAccountData;
|
||||
this.pubKeyForSign = pubKeyForSign;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
private static long doubleToLong(String d) {
|
||||
BigDecimal encodeValue = new BigDecimal(d).multiply(MULTIPLY_FACTOR);
|
||||
if (encodeValue.compareTo(MAX_NUMBER) > 0) {
|
||||
throw new IllegalArgumentException(d + " is too large.");
|
||||
}
|
||||
return encodeValue.longValue();
|
||||
|
||||
}
|
||||
|
||||
public byte[] prepareForSign(BinanceDexTransactionMessage msg)
|
||||
throws JsonProcessingException {
|
||||
SignData sd = new SignData();
|
||||
sd.setChainId(binanceAccountData.getChainId());
|
||||
sd.setAccountNumber(String.valueOf(binanceAccountData.getAccountNumber()));
|
||||
sd.setSequence(String.valueOf(binanceAccountData.getSequence()));
|
||||
sd.setMsgs(new BinanceDexTransactionMessage[]{msg});
|
||||
|
||||
sd.setMemo(options.getMemo());
|
||||
sd.setSource(String.valueOf(options.getSource()));
|
||||
sd.setData(options.getData());
|
||||
return EncodeUtils.toJsonEncodeBytes(sd);
|
||||
}
|
||||
|
||||
public byte[] encodeSignature(byte[] signatureBytes) throws IOException {
|
||||
StdSignature stdSignature = StdSignature.newBuilder().setPubKey(ByteString.copyFrom(pubKeyForSign))
|
||||
.setSignature(ByteString.copyFrom(signatureBytes))
|
||||
.setAccountNumber(binanceAccountData.getAccountNumber())
|
||||
.setSequence(binanceAccountData.getSequence())
|
||||
.build();
|
||||
|
||||
return EncodeUtils.aminoWrap(
|
||||
stdSignature.toByteArray(), MessageType.StdSignature.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public byte[] encodeStdTx(byte[] msg, byte[] signature) throws IOException {
|
||||
StdTx.Builder stdTxBuilder = StdTx.newBuilder()
|
||||
.addMsgs(ByteString.copyFrom(msg))
|
||||
.addSignatures(ByteString.copyFrom(signature))
|
||||
.setMemo(options.getMemo())
|
||||
.setSource(options.getSource());
|
||||
if (options.getData() != null) {
|
||||
stdTxBuilder = stdTxBuilder.setData(ByteString.copyFrom(options.getData()));
|
||||
}
|
||||
StdTx stdTx = stdTxBuilder.build();
|
||||
return EncodeUtils.aminoWrap(stdTx.toByteArray(), MessageType.StdTx.getTypePrefixBytes(), true);
|
||||
}
|
||||
|
||||
public static RequestBody createRequestBody(byte[] stdTx) {
|
||||
return RequestBody.create(MEDIA_TYPE, EncodeUtils.bytesToHex(stdTx));
|
||||
}
|
||||
|
||||
public TransferMessage createTransferMessage(Transfer transfer) {
|
||||
Token token = new Token();
|
||||
token.setDenom(transfer.getCoin());
|
||||
token.setAmount(doubleToLong(transfer.getAmount()));
|
||||
List<Token> coins = Collections.singletonList(token);
|
||||
|
||||
InputOutput input = new InputOutput();
|
||||
input.setAddress(transfer.getFromAddress());
|
||||
input.setCoins(coins);
|
||||
InputOutput output = new InputOutput();
|
||||
output.setAddress(transfer.getToAddress());
|
||||
output.setCoins(coins);
|
||||
|
||||
TransferMessage msgBean = new TransferMessage();
|
||||
msgBean.setInputs(Collections.singletonList(input));
|
||||
msgBean.setOutputs(Collections.singletonList(output));
|
||||
return msgBean;
|
||||
}
|
||||
|
||||
private com.tangem.blockchain.binance.proto.Send.Input toProtoInput(InputOutput input) {
|
||||
byte[] address = Crypto.decodeAddress(input.getAddress());
|
||||
com.tangem.blockchain.binance.proto.Send.Input.Builder builder =
|
||||
com.tangem.blockchain.binance.proto.Send.Input.newBuilder().setAddress(ByteString.copyFrom(address));
|
||||
|
||||
for (Token coin : input.getCoins()) {
|
||||
com.tangem.blockchain.binance.proto.Send.Token protCoin =
|
||||
com.tangem.blockchain.binance.proto.Send.Token.newBuilder().setAmount(coin.getAmount())
|
||||
.setDenom(coin.getDenom()).build();
|
||||
builder.addCoins(protCoin);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private com.tangem.blockchain.binance.proto.Send.Output toProtoOutput(InputOutput output) {
|
||||
byte[] address = Crypto.decodeAddress(output.getAddress());
|
||||
com.tangem.blockchain.binance.proto.Send.Output.Builder builder =
|
||||
com.tangem.blockchain.binance.proto.Send.Output.newBuilder().setAddress(ByteString.copyFrom(address));
|
||||
|
||||
for (Token coin : output.getCoins()) {
|
||||
com.tangem.blockchain.binance.proto.Send.Token protCoin =
|
||||
com.tangem.blockchain.binance.proto.Send.Token.newBuilder().setAmount(coin.getAmount())
|
||||
.setDenom(coin.getDenom()).build();
|
||||
builder.addCoins(protCoin);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public byte[] encodeTransferMessage(TransferMessage msg)
|
||||
throws IOException {
|
||||
com.tangem.blockchain.binance.proto.Send.Builder builder = com.tangem.blockchain.binance.proto.Send.newBuilder();
|
||||
for (InputOutput input : msg.getInputs()) {
|
||||
builder.addInputs(toProtoInput(input));
|
||||
}
|
||||
for (InputOutput output : msg.getOutputs()) {
|
||||
builder.addOutputs(toProtoOutput(output));
|
||||
}
|
||||
com.tangem.blockchain.binance.proto.Send proto = builder.build();
|
||||
return EncodeUtils.aminoWrap(proto.toByteArray(), MessageType.Send.getTypePrefixBytes(), false);
|
||||
}
|
||||
|
||||
public byte[] buildTransfer(Transfer transfer)
|
||||
throws IOException {
|
||||
TransferMessage msgBean = createTransferMessage(transfer);
|
||||
byte[] msg = encodeTransferMessage(msgBean);
|
||||
return prepareForSign(msgBean);
|
||||
// byte[] signature = encodeSignature(prepareForSign(msgBean));
|
||||
// byte[] stdTx = encodeStdTx(msg, signature);
|
||||
// return createRequestBody(stdTx);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.blockchain.binance.client.encoding.message;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
import com.tangem.blockchain.binance.client.BinanceDexConstants;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@JsonPropertyOrder(alphabetic = true)
|
||||
public class TransferMessage implements BinanceDexTransactionMessage {
|
||||
private List<InputOutput> inputs;
|
||||
private List<InputOutput> outputs;
|
||||
|
||||
public List<InputOutput> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
public void setInputs(List<InputOutput> inputs) {
|
||||
this.inputs = inputs;
|
||||
}
|
||||
|
||||
public List<InputOutput> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
public void setOutputs(List<InputOutput> outputs) {
|
||||
this.outputs = outputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this, BinanceDexConstants.BINANCE_DEX_TO_STRING_STYLE)
|
||||
.append("inputs", inputs)
|
||||
.append("outputs", outputs)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
package com.tangem.blockchain.binance.client.impl;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.tangem.blockchain.binance.client.*;
|
||||
import com.tangem.blockchain.binance.client.domain.*;
|
||||
import com.tangem.blockchain.binance.client.domain.request.ClosedOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.OpenOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TradesRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TransactionsRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BinanceDexApiAsyncRestClientImpl implements BinanceDexApiAsyncRestClient {
|
||||
private BinanceDexApi binanceDexApi;
|
||||
|
||||
public BinanceDexApiAsyncRestClientImpl(String baseUrl) {
|
||||
this.binanceDexApi = BinanceDexApiClientGenerator.createService(BinanceDexApi.class, baseUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTime(BinanceDexApiCallback<Time> callback) {
|
||||
binanceDexApi.getTime().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNodeInfo(BinanceDexApiCallback<Infos> callback) {
|
||||
binanceDexApi.getNodeInfo().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getValidators(BinanceDexApiCallback<Validators> callback) {
|
||||
binanceDexApi.getValidators().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getPeers(BinanceDexApiCallback<List<Peer>> callback) {
|
||||
binanceDexApi.getPeers().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getMarkets(BinanceDexApiCallback<List<Market>> callback) {
|
||||
binanceDexApi.getMarkets().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAccount(String address, BinanceDexApiCallback<Account> callback) {
|
||||
binanceDexApi.getAccount(address).enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAccountSequence(String address, BinanceDexApiCallback<AccountSequence> callback) {
|
||||
binanceDexApi.getAccountSequence(address).enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTransactionMetadata(String hash, BinanceDexApiCallback<TransactionMetadata> callback) {
|
||||
binanceDexApi.getTransactionMetadata(hash).enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTokens(BinanceDexApiCallback<List<Token>> callback) {
|
||||
binanceDexApi.getTokens().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOrderBook(String symbol, Integer limit, BinanceDexApiCallback<OrderBook> callback) {
|
||||
binanceDexApi.getOrderBook(symbol, limit).enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCandleStickBars(String symbol, CandlestickInterval interval,
|
||||
BinanceDexApiCallback<List<Candlestick>> callback) {
|
||||
getCandleStickBars(symbol, interval, null, null, null, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getCandleStickBars(String symbol, CandlestickInterval interval, Integer limit, Long startTime,
|
||||
Long endTime, BinanceDexApiCallback<List<Candlestick>> callback) {
|
||||
binanceDexApi.getCandlestickBars(symbol, interval.getIntervalId(), limit, startTime, endTime)
|
||||
.enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOpenOrders(String address, BinanceDexApiCallback<OrderList> callback) {
|
||||
OpenOrdersRequest request = new OpenOrdersRequest();
|
||||
request.setAddress(address);
|
||||
getOpenOrders(address, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOpenOrders(OpenOrdersRequest request, BinanceDexApiCallback<OrderList> callback) {
|
||||
binanceDexApi.getOpenOrders(request.getAddress(), request.getLimit(),
|
||||
request.getOffset(), request.getSymbol(), request.getTotal()).enqueue(
|
||||
new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void getClosedOrders(String address, BinanceDexApiCallback<OrderList> callback) {
|
||||
ClosedOrdersRequest request = new ClosedOrdersRequest();
|
||||
request.setAddress(address);
|
||||
getClosedOrders(request, callback);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
@Override
|
||||
public void getClosedOrders(ClosedOrdersRequest request, BinanceDexApiCallback<OrderList> callback) {
|
||||
String sidStr = request.getSide() == null ? null : request.getSide().name();
|
||||
List<String> statusStrList = null;
|
||||
if (request.getStatus() != null)
|
||||
statusStrList = request.getStatus().stream().map(s -> s.name()).collect(Collectors.toList());
|
||||
binanceDexApi.getClosedOrders(request.getAddress(), request.getEnd(), request.getLimit(),
|
||||
request.getLimit(), sidStr, request.getStart(), statusStrList, request.getSymbol(),
|
||||
request.getTotal()).enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getOrder(String id, BinanceDexApiCallback<Order> callback) {
|
||||
binanceDexApi.getOrder(id).enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get24HrPriceStatistics(BinanceDexApiCallback<List<TickerStatistics>> callback) {
|
||||
binanceDexApi.get24HrPriceStatistics().enqueue(new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTrades(BinanceDexApiCallback<TradePage> callback) {
|
||||
TradesRequest request = new TradesRequest();
|
||||
getTrades(request, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTrades(TradesRequest request, BinanceDexApiCallback<TradePage> callback) {
|
||||
String sideStr = request.getSide() == null ? null : request.getSide().name();
|
||||
binanceDexApi.getTrades(
|
||||
request.getAddress(), request.getBuyerOrderId(),
|
||||
request.getEnd(), request.getHeight(), request.getLimit(), request.getOffset(),
|
||||
request.getQuoteAsset(), request.getSellerOrderId(), sideStr,
|
||||
request.getStart(), request.getSymbol(), request.getTotal()).enqueue(
|
||||
new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTransactions(String address, BinanceDexApiCallback<TransactionPage> callback) {
|
||||
TransactionsRequest request = new TransactionsRequest();
|
||||
request.setAddress(address);
|
||||
getTransactions(request, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTransactions(TransactionsRequest request, BinanceDexApiCallback<TransactionPage> callback) {
|
||||
String sideStr = request.getSide() == null ? null : request.getSide().name();
|
||||
String txTypeStr = request.getTxType() != null ? request.getTxType().name() : null;
|
||||
binanceDexApi.getTransactions(
|
||||
request.getAddress(), request.getBlockHeight(), request.getEndTime(),
|
||||
request.getLimit(), request.getOffset(), sideStr,
|
||||
request.getStartTime(), request.getTxAsset(), txTypeStr).enqueue(
|
||||
new BinanceDexApiCallbackAdapter<>(callback));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
package com.tangem.blockchain.binance.client.impl;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.tangem.blockchain.binance.BinanceAccountData;
|
||||
import com.tangem.blockchain.binance.client.*;
|
||||
import com.tangem.blockchain.binance.client.domain.*;
|
||||
import com.tangem.blockchain.binance.client.domain.broadcast.*;
|
||||
import com.tangem.blockchain.binance.client.domain.request.ClosedOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.OpenOrdersRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TradesRequest;
|
||||
import com.tangem.blockchain.binance.client.domain.request.TransactionsRequest;
|
||||
import com.tangem.blockchain.binance.client.encoding.message.TransactionRequestAssembler;
|
||||
import com.tangem.blockchain.binance.client.encoding.message.TransactionRequestAssemblerExtSign;
|
||||
|
||||
import okhttp3.RequestBody;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* Binance DEX API rest client, supporting synchronous/blocking access Binance DEX's REST API.
|
||||
*/
|
||||
public class BinanceDexApiRestClientImpl implements BinanceDexApiRestClient {
|
||||
private BinanceDexApi binanceDexApi;
|
||||
|
||||
public BinanceDexApiRestClientImpl(String baseUrl) {
|
||||
this.binanceDexApi = BinanceDexApiClientGenerator.createService(BinanceDexApi.class, baseUrl);
|
||||
}
|
||||
|
||||
public Time getTime() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getTime());
|
||||
}
|
||||
|
||||
public Infos getNodeInfo() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getNodeInfo());
|
||||
}
|
||||
|
||||
public Validators getValidators() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getValidators());
|
||||
}
|
||||
|
||||
public List<Peer> getPeers() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getPeers());
|
||||
}
|
||||
|
||||
public List<Market> getMarkets() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getMarkets());
|
||||
}
|
||||
|
||||
public Account getAccount(String address) {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getAccount(address));
|
||||
}
|
||||
|
||||
public AccountSequence getAccountSequence(String address) {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getAccountSequence(address));
|
||||
}
|
||||
|
||||
public TransactionMetadata getTransactionMetadata(String hash) {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getTransactionMetadata(hash));
|
||||
}
|
||||
|
||||
public List<Token> getTokens() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getTokens());
|
||||
}
|
||||
|
||||
public OrderBook getOrderBook(String symbol, Integer limit) {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getOrderBook(symbol, limit));
|
||||
}
|
||||
|
||||
public List<Candlestick> getCandleStickBars(String symbol, CandlestickInterval interval) {
|
||||
return getCandleStickBars(symbol, interval, null, null, null);
|
||||
}
|
||||
|
||||
public List<Candlestick> getCandleStickBars(String symbol, CandlestickInterval interval, Integer limit, Long startTime, Long endTime) {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getCandlestickBars(symbol, interval.getIntervalId(), limit, startTime, endTime));
|
||||
}
|
||||
|
||||
public OrderList getOpenOrders(String address) {
|
||||
OpenOrdersRequest request = new OpenOrdersRequest();
|
||||
request.setAddress(address);
|
||||
return getOpenOrders(request);
|
||||
}
|
||||
|
||||
public OrderList getOpenOrders(OpenOrdersRequest request) {
|
||||
return BinanceDexApiClientGenerator.executeSync(
|
||||
binanceDexApi.getOpenOrders(request.getAddress(), request.getLimit(),
|
||||
request.getOffset(), request.getSymbol(), request.getTotal()));
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public OrderList getClosedOrders(String address) {
|
||||
ClosedOrdersRequest request = new ClosedOrdersRequest();
|
||||
request.setAddress(address);
|
||||
return getClosedOrders(request);
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.N)
|
||||
public OrderList getClosedOrders(ClosedOrdersRequest request) {
|
||||
String sidStr = request.getSide() == null ? null : request.getSide().name();
|
||||
List<String> statusStrList = null;
|
||||
if (request.getStatus() != null)
|
||||
statusStrList = request.getStatus().stream().map(s -> s.name()).collect(Collectors.toList());
|
||||
return BinanceDexApiClientGenerator.executeSync(
|
||||
binanceDexApi.getClosedOrders(request.getAddress(), request.getEnd(), request.getLimit(),
|
||||
request.getLimit(), sidStr, request.getStart(), statusStrList, request.getSymbol(),
|
||||
request.getTotal()));
|
||||
}
|
||||
|
||||
public Order getOrder(String id) {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.getOrder(id));
|
||||
}
|
||||
|
||||
public List<TickerStatistics> get24HrPriceStatistics() {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.get24HrPriceStatistics());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TradePage getTrades() {
|
||||
TradesRequest request = new TradesRequest();
|
||||
return getTrades(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TradePage getTrades(TradesRequest request) {
|
||||
String sideStr = request.getSide() == null ? null : request.getSide().name();
|
||||
return BinanceDexApiClientGenerator.executeSync(
|
||||
binanceDexApi.getTrades(
|
||||
request.getAddress(), request.getBuyerOrderId(),
|
||||
request.getEnd(), request.getHeight(), request.getLimit(), request.getOffset(),
|
||||
request.getQuoteAsset(), request.getSellerOrderId(), sideStr,
|
||||
request.getStart(), request.getSymbol(), request.getTotal()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionPage getTransactions(String address) {
|
||||
TransactionsRequest request = new TransactionsRequest();
|
||||
request.setAddress(address);
|
||||
return getTransactions(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransactionPage getTransactions(TransactionsRequest request) {
|
||||
String sideStr = request.getSide() != null ? request.getSide().name() : null;
|
||||
String txTypeStr = request.getTxType() != null ? request.getTxType().name() : null;
|
||||
return BinanceDexApiClientGenerator.executeSync(
|
||||
binanceDexApi.getTransactions(
|
||||
request.getAddress(), request.getBlockHeight(), request.getEndTime(),
|
||||
request.getLimit(), request.getOffset(), sideStr,
|
||||
request.getStartTime(), request.getTxAsset(), txTypeStr));
|
||||
}
|
||||
|
||||
// Broadcast and handle account sequence
|
||||
private List<TransactionMetadata> broadcast(RequestBody requestBody, boolean sync, Wallet wallet) {
|
||||
try {
|
||||
List<TransactionMetadata> metadatas =
|
||||
BinanceDexApiClientGenerator.executeSync(binanceDexApi.broadcast(sync, requestBody));
|
||||
if (!metadatas.isEmpty() && metadatas.get(0).isOk()) {
|
||||
wallet.increaseAccountSequence();
|
||||
}
|
||||
return metadatas;
|
||||
} catch (BinanceDexApiException e) {
|
||||
wallet.invalidAccountSequence();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public List<TransactionMetadata> broadcastNoWallet(RequestBody requestBody, boolean sync) throws BinanceDexApiException {
|
||||
return BinanceDexApiClientGenerator.executeSync(binanceDexApi.broadcast(sync, requestBody));
|
||||
}
|
||||
|
||||
public List<TransactionMetadata> newOrder(NewOrder newOrder, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
wallet.ensureWalletIsReady(this);
|
||||
TransactionRequestAssembler assembler = new TransactionRequestAssembler(wallet, options);
|
||||
RequestBody requestBody = assembler.buildNewOrder(newOrder);
|
||||
return broadcast(requestBody, sync, wallet);
|
||||
}
|
||||
|
||||
public List<TransactionMetadata> cancelOrder(CancelOrder cancelOrder, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
wallet.ensureWalletIsReady(this);
|
||||
TransactionRequestAssembler assembler = new TransactionRequestAssembler(wallet, options);
|
||||
RequestBody requestBody = assembler.buildCancelOrder(cancelOrder);
|
||||
return broadcast(requestBody, sync, wallet);
|
||||
}
|
||||
|
||||
public List<TransactionMetadata> transfer(Transfer transfer, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
wallet.ensureWalletIsReady(this);
|
||||
TransactionRequestAssembler assembler = new TransactionRequestAssembler(wallet, options);
|
||||
RequestBody requestBody = assembler.buildTransfer(transfer);
|
||||
return broadcast(requestBody, sync, wallet);
|
||||
}
|
||||
|
||||
public TransactionRequestAssemblerExtSign prepareTransfer(Transfer transfer, BinanceAccountData binanceAccountData, byte[] pubKeyForSign, TransactionOption options, boolean sync) {
|
||||
return new TransactionRequestAssemblerExtSign(binanceAccountData, pubKeyForSign, options);
|
||||
// RequestBody requestBody = assembler.buildTransfer(transfer);
|
||||
// return broadcast(requestBody, sync, wallet);
|
||||
}
|
||||
|
||||
public List<TransactionMetadata> freeze(TokenFreeze freeze, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
wallet.ensureWalletIsReady(this);
|
||||
TransactionRequestAssembler assembler = new TransactionRequestAssembler(wallet, options);
|
||||
RequestBody requestBody = assembler.buildTokenFreeze(freeze);
|
||||
return broadcast(requestBody, sync, wallet);
|
||||
}
|
||||
|
||||
public List<TransactionMetadata> unfreeze(TokenUnfreeze unfreeze, Wallet wallet, TransactionOption options, boolean sync)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
wallet.ensureWalletIsReady(this);
|
||||
TransactionRequestAssembler assembler = new TransactionRequestAssembler(wallet, options);
|
||||
RequestBody requestBody = assembler.buildTokenUnfreeze(unfreeze);
|
||||
return broadcast(requestBody, sync, wallet);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.blockchain.binance.network
|
||||
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.GET
|
||||
|
||||
interface BinanceApi {
|
||||
@GET("api/v1/fees")
|
||||
suspend fun getFees(): List<BinanceFee>
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package com.tangem.blockchain.binance.network
|
||||
|
||||
import com.tangem.blockchain.binance.client.BinanceDexApiClientFactory
|
||||
import com.tangem.blockchain.binance.client.BinanceDexEnvironment
|
||||
import com.tangem.blockchain.binance.client.encoding.message.TransactionRequestAssemblerExtSign
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.extensions.Result
|
||||
import com.tangem.blockchain.common.extensions.SimpleResult
|
||||
import com.tangem.blockchain.common.extensions.retryIO
|
||||
import com.tangem.blockchain.common.network.API_BINANCE
|
||||
import com.tangem.blockchain.common.network.API_BINANCE_TESTNET
|
||||
import com.tangem.blockchain.common.network.createRetrofitInstance
|
||||
import okhttp3.RequestBody
|
||||
import java.math.BigDecimal
|
||||
|
||||
class BinanceNetworkManager(isTestNet: Boolean) {
|
||||
val api = createRetrofitInstance(if (!isTestNet) API_BINANCE else API_BINANCE_TESTNET)
|
||||
.create(BinanceApi::class.java)
|
||||
val client = BinanceDexApiClientFactory.newInstance().newRestClient(
|
||||
if (!isTestNet) BinanceDexEnvironment.PROD.baseUrl else BinanceDexEnvironment.TEST_NET.baseUrl
|
||||
)
|
||||
|
||||
suspend fun getInfo(address: String): Result<BinanceInfoResponse> {
|
||||
return try {
|
||||
val accountData = retryIO { client.getAccount(address) }
|
||||
|
||||
var coinBalance = BigDecimal.ZERO
|
||||
for (balance in accountData.balances) {
|
||||
if (balance.symbol == "BNB") {
|
||||
coinBalance = balance.free.toBigDecimal()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Result.Success(BinanceInfoResponse(
|
||||
balance = coinBalance,
|
||||
accountNumber = accountData.accountNumber.toLong(),
|
||||
sequence = accountData.sequence
|
||||
))
|
||||
} catch (exception: Exception) {
|
||||
if (exception.message == "account not found") {
|
||||
Result.Success(BinanceInfoResponse(
|
||||
balance = BigDecimal.ZERO, //TODO check account not found logic
|
||||
accountNumber = null,
|
||||
sequence = null
|
||||
))
|
||||
} else {
|
||||
Result.Failure(exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getFee(): Result<BigDecimal> {
|
||||
return try {
|
||||
val feeData = api.getFees()
|
||||
var fee: BigDecimal? = null
|
||||
for (binanceFee in feeData) {
|
||||
if (binanceFee.transactionFee != null) {
|
||||
fee = binanceFee.transactionFee?.value?.toBigDecimal()
|
||||
?.movePointLeft(Blockchain.Binance.decimals.toInt())
|
||||
break
|
||||
}
|
||||
}
|
||||
return Result.Success(fee ?: throw Exception("Invalid fee response"))
|
||||
} catch (exception: Exception) {
|
||||
Result.Failure(exception)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun sendTransaction(transaction: ByteArray): SimpleResult {
|
||||
return try {
|
||||
val requestBody: RequestBody = TransactionRequestAssemblerExtSign.createRequestBody(transaction)
|
||||
val response = retryIO { client.broadcastNoWallet(requestBody, true) }
|
||||
if (response.isNotEmpty() && response[0].isOk) {
|
||||
SimpleResult.Success
|
||||
} else {
|
||||
SimpleResult.Failure(Exception("transaction failed"))
|
||||
}
|
||||
} catch (error: Exception) {
|
||||
SimpleResult.Failure(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class BinanceInfoResponse(
|
||||
val balance: BigDecimal?,
|
||||
val accountNumber: Long?,
|
||||
val sequence: Long?
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.tangem.blockchain.binance.network
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BinanceFee(
|
||||
@Json(name = "fixed_fee_params")
|
||||
var transactionFee: BinanceFeeData? = null
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class BinanceFeeData(
|
||||
@Json(name = "msg_type")
|
||||
var messageType: String? = null,
|
||||
|
||||
@Json(name = "fee")
|
||||
var value: Int? = null
|
||||
)
|
||||
|
|
@ -0,0 +1,808 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: dex.proto
|
||||
|
||||
package com.tangem.blockchain.binance.proto;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* please note the field name is the JSON name.
|
||||
* </pre>
|
||||
*
|
||||
* Protobuf type {@code transaction.CancelOrder}
|
||||
*/
|
||||
public final class CancelOrder extends
|
||||
com.google.protobuf.GeneratedMessageV3 implements
|
||||
// @@protoc_insertion_point(message_implements:transaction.CancelOrder)
|
||||
CancelOrderOrBuilder {
|
||||
private static final long serialVersionUID = 0L;
|
||||
// Use CancelOrder.newBuilder() to construct.
|
||||
private CancelOrder(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
|
||||
super(builder);
|
||||
}
|
||||
private CancelOrder() {
|
||||
sender_ = com.google.protobuf.ByteString.EMPTY;
|
||||
symbol_ = "";
|
||||
refid_ = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public final com.google.protobuf.UnknownFieldSet
|
||||
getUnknownFields() {
|
||||
return this.unknownFields;
|
||||
}
|
||||
private CancelOrder(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
this();
|
||||
if (extensionRegistry == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
int mutable_bitField0_ = 0;
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder();
|
||||
try {
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
int tag = input.readTag();
|
||||
switch (tag) {
|
||||
case 0:
|
||||
done = true;
|
||||
break;
|
||||
case 10: {
|
||||
|
||||
sender_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
String s = input.readStringRequireUtf8();
|
||||
|
||||
symbol_ = s;
|
||||
break;
|
||||
}
|
||||
case 26: {
|
||||
String s = input.readStringRequireUtf8();
|
||||
|
||||
refid_ = s;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (!parseUnknownField(
|
||||
input, unknownFields, extensionRegistry, tag)) {
|
||||
done = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
throw e.setUnfinishedMessage(this);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new com.google.protobuf.InvalidProtocolBufferException(
|
||||
e).setUnfinishedMessage(this);
|
||||
} finally {
|
||||
this.unknownFields = unknownFields.build();
|
||||
makeExtensionsImmutable();
|
||||
}
|
||||
}
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return com.tangem.blockchain.binance.proto.Transaction.internal_static_transaction_CancelOrder_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return com.tangem.blockchain.binance.proto.Transaction.internal_static_transaction_CancelOrder_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
com.tangem.blockchain.binance.proto.CancelOrder.class, com.tangem.blockchain.binance.proto.CancelOrder.Builder.class);
|
||||
}
|
||||
|
||||
public static final int SENDER_FIELD_NUMBER = 1;
|
||||
private com.google.protobuf.ByteString sender_;
|
||||
/**
|
||||
* <pre>
|
||||
* 0x166E681B // hardcoded, object type prefix in 4 bytes
|
||||
* </pre>
|
||||
*
|
||||
* <code>bytes sender = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getSender() {
|
||||
return sender_;
|
||||
}
|
||||
|
||||
public static final int SYMBOL_FIELD_NUMBER = 2;
|
||||
private volatile Object symbol_;
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public String getSymbol() {
|
||||
Object ref = symbol_;
|
||||
if (ref instanceof String) {
|
||||
return (String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
symbol_ = s;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getSymbolBytes() {
|
||||
Object ref = symbol_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
symbol_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
public static final int REFID_FIELD_NUMBER = 3;
|
||||
private volatile Object refid_;
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public String getRefid() {
|
||||
Object ref = refid_;
|
||||
if (ref instanceof String) {
|
||||
return (String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
refid_ = s;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getRefidBytes() {
|
||||
Object ref = refid_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
refid_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
private byte memoizedIsInitialized = -1;
|
||||
@Override
|
||||
public final boolean isInitialized() {
|
||||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized == 1) return true;
|
||||
if (isInitialized == 0) return false;
|
||||
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
if (!sender_.isEmpty()) {
|
||||
output.writeBytes(1, sender_);
|
||||
}
|
||||
if (!getSymbolBytes().isEmpty()) {
|
||||
com.google.protobuf.GeneratedMessageV3.writeString(output, 2, symbol_);
|
||||
}
|
||||
if (!getRefidBytes().isEmpty()) {
|
||||
com.google.protobuf.GeneratedMessageV3.writeString(output, 3, refid_);
|
||||
}
|
||||
unknownFields.writeTo(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSize;
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (!sender_.isEmpty()) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, sender_);
|
||||
}
|
||||
if (!getSymbolBytes().isEmpty()) {
|
||||
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, symbol_);
|
||||
}
|
||||
if (!getRefidBytes().isEmpty()) {
|
||||
size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, refid_);
|
||||
}
|
||||
size += unknownFields.getSerializedSize();
|
||||
memoizedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof com.tangem.blockchain.binance.proto.CancelOrder)) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
com.tangem.blockchain.binance.proto.CancelOrder other = (com.tangem.blockchain.binance.proto.CancelOrder) obj;
|
||||
|
||||
if (!getSender()
|
||||
.equals(other.getSender())) return false;
|
||||
if (!getSymbol()
|
||||
.equals(other.getSymbol())) return false;
|
||||
if (!getRefid()
|
||||
.equals(other.getRefid())) return false;
|
||||
if (!unknownFields.equals(other.unknownFields)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (memoizedHashCode != 0) {
|
||||
return memoizedHashCode;
|
||||
}
|
||||
int hash = 41;
|
||||
hash = (19 * hash) + getDescriptor().hashCode();
|
||||
hash = (37 * hash) + SENDER_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getSender().hashCode();
|
||||
hash = (37 * hash) + SYMBOL_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getSymbol().hashCode();
|
||||
hash = (37 * hash) + REFID_FIELD_NUMBER;
|
||||
hash = (53 * hash) + getRefid().hashCode();
|
||||
hash = (29 * hash) + unknownFields.hashCode();
|
||||
memoizedHashCode = hash;
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
java.nio.ByteBuffer data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
java.nio.ByteBuffer data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return PARSER.parseFrom(data, extensionRegistry);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseDelimitedWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input);
|
||||
}
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return com.google.protobuf.GeneratedMessageV3
|
||||
.parseWithIOException(PARSER, input, extensionRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder() {
|
||||
return DEFAULT_INSTANCE.toBuilder();
|
||||
}
|
||||
public static Builder newBuilder(com.tangem.blockchain.binance.proto.CancelOrder prototype) {
|
||||
return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
|
||||
}
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return this == DEFAULT_INSTANCE
|
||||
? new Builder() : new Builder().mergeFrom(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder newBuilderForType(
|
||||
BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* please note the field name is the JSON name.
|
||||
* </pre>
|
||||
*
|
||||
* Protobuf type {@code transaction.CancelOrder}
|
||||
*/
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
|
||||
// @@protoc_insertion_point(builder_implements:transaction.CancelOrder)
|
||||
com.tangem.blockchain.binance.proto.CancelOrderOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return com.tangem.blockchain.binance.proto.Transaction.internal_static_transaction_CancelOrder_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return com.tangem.blockchain.binance.proto.Transaction.internal_static_transaction_CancelOrder_fieldAccessorTable
|
||||
.ensureFieldAccessorsInitialized(
|
||||
com.tangem.blockchain.binance.proto.CancelOrder.class, com.tangem.blockchain.binance.proto.CancelOrder.Builder.class);
|
||||
}
|
||||
|
||||
// Construct using com.tangem.blockchain.binance.proto.CancelOrder.newBuilder()
|
||||
private Builder() {
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
|
||||
private Builder(
|
||||
BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessageV3
|
||||
.alwaysUseFieldBuilders) {
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
sender_ = com.google.protobuf.ByteString.EMPTY;
|
||||
|
||||
symbol_ = "";
|
||||
|
||||
refid_ = "";
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return com.tangem.blockchain.binance.proto.Transaction.internal_static_transaction_CancelOrder_descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.tangem.blockchain.binance.proto.CancelOrder getDefaultInstanceForType() {
|
||||
return com.tangem.blockchain.binance.proto.CancelOrder.getDefaultInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.tangem.blockchain.binance.proto.CancelOrder build() {
|
||||
com.tangem.blockchain.binance.proto.CancelOrder result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.tangem.blockchain.binance.proto.CancelOrder buildPartial() {
|
||||
com.tangem.blockchain.binance.proto.CancelOrder result = new com.tangem.blockchain.binance.proto.CancelOrder(this);
|
||||
result.sender_ = sender_;
|
||||
result.symbol_ = symbol_;
|
||||
result.refid_ = refid_;
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder clone() {
|
||||
return super.clone();
|
||||
}
|
||||
@Override
|
||||
public Builder setField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return super.setField(field, value);
|
||||
}
|
||||
@Override
|
||||
public Builder clearField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field) {
|
||||
return super.clearField(field);
|
||||
}
|
||||
@Override
|
||||
public Builder clearOneof(
|
||||
com.google.protobuf.Descriptors.OneofDescriptor oneof) {
|
||||
return super.clearOneof(oneof);
|
||||
}
|
||||
@Override
|
||||
public Builder setRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
int index, Object value) {
|
||||
return super.setRepeatedField(field, index, value);
|
||||
}
|
||||
@Override
|
||||
public Builder addRepeatedField(
|
||||
com.google.protobuf.Descriptors.FieldDescriptor field,
|
||||
Object value) {
|
||||
return super.addRepeatedField(field, value);
|
||||
}
|
||||
@Override
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof com.tangem.blockchain.binance.proto.CancelOrder) {
|
||||
return mergeFrom((com.tangem.blockchain.binance.proto.CancelOrder)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.tangem.blockchain.binance.proto.CancelOrder other) {
|
||||
if (other == com.tangem.blockchain.binance.proto.CancelOrder.getDefaultInstance()) return this;
|
||||
if (other.getSender() != com.google.protobuf.ByteString.EMPTY) {
|
||||
setSender(other.getSender());
|
||||
}
|
||||
if (!other.getSymbol().isEmpty()) {
|
||||
symbol_ = other.symbol_;
|
||||
onChanged();
|
||||
}
|
||||
if (!other.getRefid().isEmpty()) {
|
||||
refid_ = other.refid_;
|
||||
onChanged();
|
||||
}
|
||||
this.mergeUnknownFields(other.unknownFields);
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isInitialized() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
com.tangem.blockchain.binance.proto.CancelOrder parsedMessage = null;
|
||||
try {
|
||||
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||
parsedMessage = (com.tangem.blockchain.binance.proto.CancelOrder) e.getUnfinishedMessage();
|
||||
throw e.unwrapIOException();
|
||||
} finally {
|
||||
if (parsedMessage != null) {
|
||||
mergeFrom(parsedMessage);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private com.google.protobuf.ByteString sender_ = com.google.protobuf.ByteString.EMPTY;
|
||||
/**
|
||||
* <pre>
|
||||
* 0x166E681B // hardcoded, object type prefix in 4 bytes
|
||||
* </pre>
|
||||
*
|
||||
* <code>bytes sender = 1;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString getSender() {
|
||||
return sender_;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* 0x166E681B // hardcoded, object type prefix in 4 bytes
|
||||
* </pre>
|
||||
*
|
||||
* <code>bytes sender = 1;</code>
|
||||
*/
|
||||
public Builder setSender(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
sender_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* 0x166E681B // hardcoded, object type prefix in 4 bytes
|
||||
* </pre>
|
||||
*
|
||||
* <code>bytes sender = 1;</code>
|
||||
*/
|
||||
public Builder clearSender() {
|
||||
|
||||
sender_ = getDefaultInstance().getSender();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
private Object symbol_ = "";
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public String getSymbol() {
|
||||
Object ref = symbol_;
|
||||
if (!(ref instanceof String)) {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
symbol_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getSymbolBytes() {
|
||||
Object ref = symbol_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
symbol_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public Builder setSymbol(
|
||||
String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
symbol_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public Builder clearSymbol() {
|
||||
|
||||
symbol_ = getDefaultInstance().getSymbol();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
public Builder setSymbolBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
checkByteStringIsUtf8(value);
|
||||
|
||||
symbol_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
private Object refid_ = "";
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public String getRefid() {
|
||||
Object ref = refid_;
|
||||
if (!(ref instanceof String)) {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
refid_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (String) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public com.google.protobuf.ByteString
|
||||
getRefidBytes() {
|
||||
Object ref = refid_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8(
|
||||
(String) ref);
|
||||
refid_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public Builder setRefid(
|
||||
String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
refid_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public Builder clearRefid() {
|
||||
|
||||
refid_ = getDefaultInstance().getRefid();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
public Builder setRefidBytes(
|
||||
com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
checkByteStringIsUtf8(value);
|
||||
|
||||
refid_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public final Builder setUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.setUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Builder mergeUnknownFields(
|
||||
final com.google.protobuf.UnknownFieldSet unknownFields) {
|
||||
return super.mergeUnknownFields(unknownFields);
|
||||
}
|
||||
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:transaction.CancelOrder)
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:transaction.CancelOrder)
|
||||
private static final com.tangem.blockchain.binance.proto.CancelOrder DEFAULT_INSTANCE;
|
||||
static {
|
||||
DEFAULT_INSTANCE = new com.tangem.blockchain.binance.proto.CancelOrder();
|
||||
}
|
||||
|
||||
public static com.tangem.blockchain.binance.proto.CancelOrder getDefaultInstance() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
private static final com.google.protobuf.Parser<CancelOrder>
|
||||
PARSER = new com.google.protobuf.AbstractParser<CancelOrder>() {
|
||||
@Override
|
||||
public CancelOrder parsePartialFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return new CancelOrder(input, extensionRegistry);
|
||||
}
|
||||
};
|
||||
|
||||
public static com.google.protobuf.Parser<CancelOrder> parser() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.google.protobuf.Parser<CancelOrder> getParserForType() {
|
||||
return PARSER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.tangem.blockchain.binance.proto.CancelOrder getDefaultInstanceForType() {
|
||||
return DEFAULT_INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: dex.proto
|
||||
|
||||
package com.tangem.blockchain.binance.proto;
|
||||
|
||||
public interface CancelOrderOrBuilder extends
|
||||
// @@protoc_insertion_point(interface_extends:transaction.CancelOrder)
|
||||
com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 0x166E681B // hardcoded, object type prefix in 4 bytes
|
||||
* </pre>
|
||||
*
|
||||
* <code>bytes sender = 1;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString getSender();
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
String getSymbol();
|
||||
/**
|
||||
* <pre>
|
||||
* symbol for trading pair in full name of the tokens
|
||||
* </pre>
|
||||
*
|
||||
* <code>string symbol = 2;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getSymbolBytes();
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
String getRefid();
|
||||
/**
|
||||
* <pre>
|
||||
* order id of the one to cancel
|
||||
* </pre>
|
||||
*
|
||||
* <code>string refid = 3;</code>
|
||||
*/
|
||||
com.google.protobuf.ByteString
|
||||
getRefidBytes();
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue