11package com.invertedx.sentinelx.api
22
33import android.content.Context
4- import android.preference.PreferenceManager
54import android.util.Log
65import com.invertedx.sentinelx.BuildConfig
76import com.invertedx.sentinelx.SentinelxApp
8- import com.invertedx.sentinelx.i
97import com.invertedx.sentinelx.tor.TorManager
108import com.invertedx.sentinelx.utils.LoggingInterceptor
119import com.invertedx.sentinelx.utils.SentinalPrefs
1210import io.reactivex.Observable
13- import okhttp3.FormBody
14- import okhttp3.OkHttpClient
15- import okhttp3.Request
16- import okhttp3.RequestBody
11+ import io.reactivex.Single
12+ import okhttp3.*
13+ import org.json.JSONObject
14+ import java.io.IOException
1715import java.util.concurrent.TimeUnit
1816import javax.net.ssl.HostnameVerifier
1917import javax.net.ssl.SSLContext
@@ -37,18 +35,18 @@ class ApiService(private val applicationContext: Context) {
3735
3836
3937 fun getTxAndXPUBData (XpubOrAddress : String ): Observable <String > {
38+ makeClient();
39+
4040 val baseAddress = getBaseUrl()
4141 val url = if (SentinelxApp .accessToken.isNotEmpty()) " ${baseAddress} multiaddr?active=$XpubOrAddress &at=${SentinelxApp .accessToken} " else " ${baseAddress} multiaddr?active=$XpubOrAddress "
4242
43- Log .i(" API" , " CALL url -> $url " )
4443 return Observable .fromCallable {
4544 val request = Request .Builder ()
4645 .url(url)
4746 .build()
4847 val response = client.newCall(request).execute()
4948 try {
5049 val content = response.body!! .string()
51- Log .i(" API" , " response -> $content " )
5250 return @fromCallable content
5351 } catch (ex: Exception ) {
5452 return @fromCallable " {}"
@@ -68,6 +66,12 @@ class ApiService(private val applicationContext: Context) {
6866 return SentinelxApp .dojoUrl
6967 }
7068
69+ if (SentinalPrefs (applicationContext).dojoKey != null ) {
70+ SentinelxApp .accessToken = SentinalPrefs (applicationContext).dojoKey!!
71+ }
72+ if (SentinalPrefs (applicationContext).dojoUrl != null ) {
73+ return SentinalPrefs (applicationContext).dojoUrl!!
74+ }
7175 return if (TorManager .getInstance(this .applicationContext)?.isConnected!! ) {
7276 if (SentinelxApp .isTestNet()) SAMOURAI_API2_TESTNET_TOR_DIST else SAMOURAI_API2_TOR_DIST
7377 } else {
@@ -88,7 +92,6 @@ class ApiService(private val applicationContext: Context) {
8892 val response = client.newCall(request).execute()
8993 try {
9094 val content = response.body!! .string()
91- Log .i(" API" , " response -> $content " )
9295 return @fromCallable content
9396 } catch (ex: Exception ) {
9497 throw ex
@@ -99,6 +102,9 @@ class ApiService(private val applicationContext: Context) {
99102
100103
101104 fun authenticate (url : String , key : String ): Observable <String > {
105+
106+ makeClient();
107+
102108 val targetUrl = " $url /auth/login?apikey=$key "
103109 return Observable .fromCallable {
104110
@@ -119,6 +125,7 @@ class ApiService(private val applicationContext: Context) {
119125
120126
121127 fun getUnspent (xpubOrAddress : String ): Observable <String > {
128+
122129 makeClient()
123130
124131 val baseAddress = getBaseUrl()
@@ -141,6 +148,35 @@ class ApiService(private val applicationContext: Context) {
141148 }
142149 }
143150
151+
152+ fun pushTx (hex : String ): Observable <String > {
153+
154+ makeClient()
155+
156+ val baseAddress = getBaseUrl()
157+ val baseUrl = if (SentinelxApp .accessToken.isNotEmpty()) " ${baseAddress} pushtx/?at=${SentinelxApp .accessToken} " else " ${baseAddress} pushtx" ;
158+
159+ return Observable .fromCallable {
160+
161+ val request = Request .Builder ()
162+ .url(baseUrl)
163+ .method(" POST" , FormBody .Builder ()
164+ .add(" tx" , hex)
165+ .build())
166+ .build()
167+
168+ val response = client.newCall(request).execute()
169+ try {
170+ val content = response.body!! .string()
171+ return @fromCallable content
172+ } catch (ex: Exception ) {
173+ throw ex;
174+ }
175+
176+ }
177+ }
178+
179+
144180 fun addHDAccount (xpub : String , bip : String ): Observable <String > {
145181
146182 makeClient()
@@ -154,8 +190,6 @@ class ApiService(private val applicationContext: Context) {
154190 .add(" segwit" , bip)
155191 .build()
156192
157- Log .i(" url" , baseUrl.toString())
158- Log .i(" requestBody" , requestBody.toString())
159193 return Observable .fromCallable {
160194
161195 val request = Request .Builder ()
@@ -166,13 +200,12 @@ class ApiService(private val applicationContext: Context) {
166200 client.connectTimeoutMillis
167201 val response = client.newCall(request).execute()
168202 val content = response.body!! .string()
169- Log .i(" API" , " response -> $content " )
170203 return @fromCallable content
171204
172205 }
173206 }
174207
175-
208+
176209 fun makeClient () {
177210 val builder = OkHttpClient .Builder ()
178211 if (BuildConfig .DEBUG ) {
@@ -182,6 +215,7 @@ class ApiService(private val applicationContext: Context) {
182215 getHostNameVerifier(builder)
183216 builder.proxy(TorManager .getInstance(this .applicationContext)?.getProxy())
184217 }
218+ builder.addInterceptor(LogEntry (this ))
185219 val prefs = SentinalPrefs (applicationContext)
186220
187221 var timeout = 90L ;
@@ -193,6 +227,7 @@ class ApiService(private val applicationContext: Context) {
193227 client = builder.build()
194228 }
195229
230+
196231 @Throws(Exception ::class )
197232 private fun getHostNameVerifier (clientBuilder : OkHttpClient .Builder ) {
198233
@@ -220,4 +255,70 @@ class ApiService(private val applicationContext: Context) {
220255
221256 }
222257
223- }
258+ // Generic post request handler
259+ fun postRequest (url : String , requestBody : RequestBody ): Single <String > {
260+ return Single .fromCallable {
261+ val request = Request .Builder ()
262+ .url(url)
263+ .method(" POST" , requestBody)
264+ .build()
265+ val response = client.newCall(request).execute()
266+
267+ try {
268+ val content = response.body!! .string()
269+ return @fromCallable content
270+ } catch (ex: Exception ) {
271+ throw ex
272+ }
273+ }
274+
275+ }
276+
277+ // Generic get request handler
278+ fun getRequest (url : String ): Single <String > {
279+ return Single .fromCallable {
280+ val request = Request .Builder ()
281+ .url(url)
282+ .build()
283+ val response = client.newCall(request).execute()
284+
285+ try {
286+ val content = response.body!! .string()
287+ return @fromCallable content
288+ } catch (ex: Exception ) {
289+ throw ex
290+ }
291+ }
292+
293+ }
294+
295+
296+ internal class LogEntry (val apiService : ApiService ) : Interceptor {
297+
298+ @Throws(IOException ::class )
299+ override fun intercept (chain : Interceptor .Chain ): Response {
300+ val obj = JSONObject ();
301+ val request = chain.request()
302+ val t1 = System .nanoTime()
303+ obj.put(" url" , request.url.toString());
304+ obj.put(" method" , request.method);
305+ obj.put(" init_time" , System .currentTimeMillis());
306+ val response = chain.proceed(request)
307+ val t2 = System .nanoTime()
308+ obj.put(" time" , (t2 - t1) / 1e6);
309+ obj.put(" status" , response.code);
310+ obj.put(" network" , " " );
311+ if (SentinelxApp .dojoUrl.isNotBlank()) {
312+ if (SentinelxApp .dojoUrl.contains(request.url.toUri().host)) {
313+ obj.put(" network" , " DOJO" );
314+ }
315+ }
316+
317+ SentinelxApp .netWorkLog.put(obj);
318+ return response
319+ }
320+ }
321+
322+
323+ }
324+
0 commit comments