@@ -3,6 +3,7 @@ package org.blockstack.android.sdk
33import android.util.Log
44import com.colendi.ecies.EncryptedResultForm
55import com.colendi.ecies.Encryption
6+ import kotlinx.coroutines.CoroutineDispatcher
67import kotlinx.coroutines.Dispatchers
78import kotlinx.coroutines.withContext
89import me.uport.sdk.core.hexToByteArray
@@ -34,7 +35,8 @@ const val SIGNATURE_FILE_EXTENSION = ".sig"
3435class BlockstackSession (private val sessionStore : ISessionStore , private val appConfig : BlockstackConfig ? = null ,
3536 private val callFactory : Call .Factory = OkHttpClient (),
3637 val blockstack : Blockstack = Blockstack (),
37- val hub : Hub = Hub (callFactory)) {
38+ val hub : Hub = Hub (callFactory),
39+ val dispatcher : CoroutineDispatcher = Dispatchers .IO ) {
3840
3941 private var appPrivateKey: String?
4042 var gaiaHubConfig: GaiaHubConfig ? = null
@@ -53,37 +55,37 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
5355 * @return result object with the user data after sign-in or with an error
5456 *
5557 */
56- suspend fun handlePendingSignIn (authResponse : String ): Result <UserData > {
58+ suspend fun handlePendingSignIn (authResponse : String ): Result <out UserData > = withContext(dispatcher) {
5759 val transitKey = sessionStore.getTransitPrivateKey()
5860 val nameLookupUrl = sessionStore.sessionData.json.optString(" core-node" , " https://core.blockstack.org" )
5961
6062 val tokenTriple = try {
6163 blockstack.decodeToken(authResponse)
6264 } catch (e: IllegalArgumentException ) {
63- return Result (null , ResultError (ErrorCode .LoginFailedError , " The authResponse parameter is an invalid base64 encoded token\n " +
65+ return @withContext Result (null , ResultError (ErrorCode .LoginFailedError , " The authResponse parameter is an invalid base64 encoded token\n " +
6466 " 2 dots requires\n " +
6567 " Auth response: $authResponse " ))
6668 }
6769 val tokenPayload = tokenTriple.second
6870 val isValidToken = blockstack.verifyToken(authResponse)
6971
7072 if (! isValidToken) {
71- return Result (null , ResultError (ErrorCode .LoginFailedError , " invalid auth response" ))
73+ return @withContext Result (null , ResultError (ErrorCode .LoginFailedError , " invalid auth response" ))
7274 }
7375 val appPrivateKey = decrypt(tokenPayload.getString(" private_key" ), transitKey)
7476
7577 if (appPrivateKey == null ) {
76- return Result (null , ResultError (ErrorCode .LoginFailedError , " auth response used different transient key" ))
78+ return @withContext Result (null , ResultError (ErrorCode .LoginFailedError , " auth response used different transient key" ))
7779 }
7880
7981 val coreSessionToken = decrypt(tokenPayload.optString(" core_token" ), transitKey)
8082
8183 val userData = authResponseToUserData(tokenPayload, nameLookupUrl, appPrivateKey, coreSessionToken, authResponse)
8284
83- this .appPrivateKey = appPrivateKey
85+ this @BlockstackSession .appPrivateKey = appPrivateKey
8486 sessionStore.updateUserData(userData)
8587
86- return Result (userData)
88+ return @withContext Result (userData)
8789 }
8890
8991 suspend fun handleUnencryptedSignIn (authResponse : String ): Result <UserData > {
@@ -130,7 +132,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
130132 private suspend fun extractProfile (tokenPayload : JSONObject , nameLookupUrl : String ): JSONObject {
131133 val profileUrl = tokenPayload.optStringOrNull(" profile_url" )
132134 if (profileUrl != null && profileUrl.isNotBlank()) {
133- return withContext(Dispatchers . IO ) {
135+ return withContext(dispatcher ) {
134136 val request = Request .Builder ().url(profileUrl)
135137 .build()
136138 val response = callFactory.newCall(request).execute()
@@ -222,7 +224,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
222224 */
223225 suspend fun getFile (path : String , options : GetFileOptions ): Result <out Any > {
224226 Log .d(TAG , " getFile: path: $path options: $options " )
225- return withContext(Dispatchers . IO ) {
227+ return withContext(dispatcher ) {
226228 val urlResult = getFileUrl(path, options)
227229 if (urlResult.hasErrors) {
228230 return @withContext urlResult
@@ -313,12 +315,10 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
313315 }
314316
315317 suspend fun getGaiaAddress (appDomain : String , username : String ): String {
316- val fileUrl = blockstack.getUserAppFileUrl(" /" , username, appDomain, null )
317- val address = Regex (" ([13][a-km-zA-HJ-NP-Z0-9]{26,35})" ).find(fileUrl)?.value
318- if (address != null ) {
319- return address
320- } else {
321- return " "
318+ return withContext(dispatcher) {
319+ val fileUrl = blockstack.getUserAppFileUrl(" /" , username, appDomain, null )
320+ val address = Regex (" ([13][a-km-zA-HJ-NP-Z0-9]{26,35})" ).find(fileUrl)?.value
321+ return @withContext address ? : " "
322322 }
323323 }
324324
@@ -333,7 +333,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
333333 * @property a result object wiht a `String` representation of a url from
334334 * which you can read the file that was just put.
335335 */
336- suspend fun putFile (path : String , content : Any , options : PutFileOptions ): Result <out String > {
336+ suspend fun putFile (path : String , content : Any , options : PutFileOptions ): Result <out String > = withContext(dispatcher) {
337337 Log .d(TAG , " putFile: path: ${path} options: ${options} " )
338338 val gaiaHubConfiguration = getOrSetLocalGaiaHubConnection()
339339 val valid = content is String || content is ByteArray
@@ -378,7 +378,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
378378 }
379379 }
380380
381- return withContext( Dispatchers . IO ) {
381+
382382 try {
383383 val response = hub.uploadToGaiaHub(path, requestContent, gaiaHubConfiguration, contentType)
384384 if (! response.isSuccessful) {
@@ -409,7 +409,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
409409 ? : e.toString()))
410410 }
411411
412- }
412+
413413 }
414414
415415 private fun getSignKey (options : PutFileOptions ): String {
@@ -440,21 +440,21 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
440440 }
441441
442442
443- suspend fun deleteFile (path : String , options : DeleteFileOptions = DeleteFileOptions ()): Result <out Unit > {
443+ suspend fun deleteFile (path : String , options : DeleteFileOptions = DeleteFileOptions ()): Result <out Unit > = withContext(dispatcher) {
444444 try {
445445 val response = hub.deleteFromGaiaHub(path, options.gaiaHubConfig ? : gaiaHubConfig!! )
446446 if (response != null ) {
447447 if (response.isSuccessful) {
448- return Result (Unit )
448+ return @withContext Result (Unit )
449449 } else {
450- return Result (null , ResultError (ErrorCode .NetworkError ,
450+ return @withContext Result (null , ResultError (ErrorCode .NetworkError ,
451451 " failed to delete $path " , response.code.toString()))
452452 }
453453 } else {
454- return Result (null , ResultError (ErrorCode .UnknownError , " failed to delete $path " ))
454+ return @withContext Result (null , ResultError (ErrorCode .UnknownError , " failed to delete $path " ))
455455 }
456456 } catch (e: Exception ) {
457- return Result (null , ResultError (ErrorCode .UnknownError ,
457+ return @withContext Result (null , ResultError (ErrorCode .UnknownError ,
458458 " failed to delete $path : ${e.message ? : e.toString()} " ))
459459 }
460460 }
@@ -487,7 +487,6 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
487487 blockstack.getUserAppFileUrl(path, options.username,
488488 options.app ? : appConfig!! .appDomain.getOrigin(),
489489 options.zoneFileLookupURL?.toString())
490-
491490 } else {
492491 val gaiaHubConfig = getOrSetLocalGaiaHubConnection()
493492 hub.getFullReadUrl(path, gaiaHubConfig)
@@ -506,7 +505,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app
506505 }
507506
508507 val request = buildListFilesRequest(page, gaiaHubConfig ? : getHubConfig())
509- val response = withContext(Dispatchers . IO ) {
508+ val response = withContext(dispatcher ) {
510509 callFactory.newCall(request).execute()
511510 }
512511 if (! response.isSuccessful) {
0 commit comments