From f4a9df5f413b1d16f57863149b472000eba27272 Mon Sep 17 00:00:00 2001 From: FilipeA Date: Fri, 16 Jul 2021 17:36:50 +0100 Subject: [PATCH 1/3] updated: Core Url (https://stacks-node-api.stacks.co) --- CHANGELOG.md | 4 ++ blockstack-sdk/build.gradle | 2 +- .../org/blockstack/android/sdk/Blockstack.kt | 40 ++++++++++++++----- .../android/sdk/BlockstackSession.kt | 5 ++- .../java/org/blockstack/android/sdk/DIDs.kt | 6 +-- .../org/blockstack/android/sdk/Defaults.kt | 2 +- .../android/sdk/extensions/Addresses.kt | 20 ++++++++-- .../android/sdk/extensions/AddressesTest.kt | 2 + .../org/blockstack/android/MainActivity.kt | 6 ++- 9 files changed, 63 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a84caa1a..1bc71af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unrelease +## [0.6.4] - 2021-07-16 +### Changed +- Default Core API endpoint (https://stacks-node-api.stacks.co) + ## [0.6.3] - 2021-07-01 ### Added - ability to generate Stacks Addresses diff --git a/blockstack-sdk/build.gradle b/blockstack-sdk/build.gradle index a01cb768..223ca2bc 100644 --- a/blockstack-sdk/build.gradle +++ b/blockstack-sdk/build.gradle @@ -12,7 +12,7 @@ android { minSdkVersion 21 targetSdkVersion 30 versionCode 2 - versionName "0.6.3" + versionName "0.6.4" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt index e267b781..05bcd5b3 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt @@ -22,6 +22,7 @@ import okhttp3.Request import okhttp3.Response import org.blockstack.android.sdk.extensions.toBtcAddress import org.blockstack.android.sdk.extensions.toHexPublicKey64 +import org.blockstack.android.sdk.extensions.toStxAddress import org.blockstack.android.sdk.model.* import org.json.JSONArray import org.json.JSONException @@ -98,8 +99,8 @@ class Blockstack(private val callFactory: Call.Factory = OkHttpClient(), "" }, "profile_url" to null, - "hubUrl" to "https://hub.blockstack.org", - "blockstackAPIUrl" to "https://core.blockstack.org", + "hubUrl" to "https://hub.blockstack.org", //TODO: here is what? + "blockstackAPIUrl" to "https://core.blockstack.org", //TODO: here is what? "associationToken" to null, "version" to VERSION ) @@ -296,8 +297,21 @@ class Blockstack(private val callFactory: Call.Factory = OkHttpClient(), val body = response.body!!.string() val nameInfo = JSONObject(body) val nameOwningAddress = nameInfo.optString("address") - val addressFromIssuer = DIDs.getAddressFromDID(payload.optString("iss")) - return nameOwningAddress.isNotEmpty() && nameOwningAddress == addressFromIssuer + val addressFromIssuer = DIDs.getAddressFromDID(payload.optString("iss")) ?: "" + + //Check if the address is a stx address + return if (nameOwningAddress.startsWith("S")) { + if (nameOwningAddress.isNotEmpty() && nameOwningAddress == addressFromIssuer) { + true + } else { + // Backward Compatibility (Address STX with BTC issuer) + // if the address is not the same, check if the profile belongs to the owner + nameInfo.optString("zonefile").contains(addressFromIssuer) + } + } else { + // legacy + nameOwningAddress.isNotEmpty() && nameOwningAddress == addressFromIssuer + } } else { return false } @@ -519,17 +533,21 @@ class Blockstack(private val callFactory: Call.Factory = OkHttpClient(), } val issuerPublicKey = payload.getJSONObject("issuer").getString("publicKey") - val uncompressedAddress = issuerPublicKey.toBtcAddress() + val uncompressedBtcAddress = issuerPublicKey.toBtcAddress() + val uncompressedStxAddress = issuerPublicKey.toStxAddress(true) - if (publicKeyOrAddress == issuerPublicKey) { - // pass - } else { - if (publicKeyOrAddress == uncompressedAddress) { + if (publicKeyOrAddress == issuerPublicKey) { // pass } else { - throw Error("Token issuer public key does not match the verifying value") + when (publicKeyOrAddress) { + uncompressedBtcAddress -> { /* Pass */} + uncompressedStxAddress -> { /* Pass */} + else -> { + throw Error("Token issuer public key does not match the verifying value") + } + } } - } + return ProfileToken(tokenTripleToJSON(decodedToken)) diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt index 517cd7c6..62e53ae2 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt @@ -60,7 +60,7 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app */ suspend fun handlePendingSignIn(authResponse: String): Result = withContext(dispatcher) { val transitKey = sessionStore.getTransitPrivateKey() - val nameLookupUrl = sessionStore.sessionData.json.optString("core-node", "https://core.blockstack.org") + val nameLookupUrl = sessionStore.sessionData.json.optString("core-node", "stacks-node-api.stacks.co") val tokenTriple = try { blockstack.decodeToken(authResponse) @@ -92,7 +92,8 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app } suspend fun handleUnencryptedSignIn(authResponse: String): Result { - val nameLookupUrl = sessionStore.sessionData.json.optString("core-node", "https://core.blockstack.org") + //TODO: change here + val nameLookupUrl = sessionStore.sessionData.json.optString("core-node", "stacks-node-api.stacks.co") val tokenTriple = blockstack.decodeToken(authResponse) val tokenPayload = tokenTriple.second diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt index 70c04891..105c9563 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt @@ -2,8 +2,6 @@ package org.blockstack.android.sdk import me.uport.sdk.universaldid.* import okhttp3.Call -import okhttp3.Request -import org.json.JSONObject import java.util.* class DIDs { @@ -19,8 +17,10 @@ class DIDs { if (didType == "btc-addr") { return did.split(':')[2] + }else if (didType == "stx-addr") { + return did.split(':')[2] } else { - return null + return null } } diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Defaults.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Defaults.kt index 770930e3..18aa9e81 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Defaults.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Defaults.kt @@ -1,7 +1,7 @@ package org.blockstack.android.sdk const val BLOCKSTACK_DEFAULT_GAIA_HUB_URL = "https://hub.blockstack.org" -const val DEFAULT_CORE_API_ENDPOINT = "https://core.blockstack.org" +const val DEFAULT_CORE_API_ENDPOINT = "https://stacks-node-api.stacks.co" const val DEFAULT_BLOCKSTACK_ID_HOST = "https://app.blockstack.org" const val LEGACY_BLOCKSTACK_ID_HOST = "https://browser.blockstack.org/auth" const val VERSION = "1.3.1" diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/extensions/Addresses.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/extensions/Addresses.kt index b54a9582..a860e624 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/extensions/Addresses.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/extensions/Addresses.kt @@ -15,20 +15,32 @@ fun ECKeyPair.toHexPublicKey64(): String { return this.getCompressedPublicKey().toNoPrefixHexString() } -fun ECKeyPair.toStxAddress(): String { +fun String.toStxAddress(sPrefix: Boolean = false): String { + val sha256 = hexToByteArray().sha256() + val hash160 = sha256.digestRipemd160() + val extended = "b0${hash160.toNoPrefixHexString()}" + val cs = checksum("16${hash160.toNoPrefixHexString()}") + + val prefix = if(sPrefix) "S" else "" + return prefix + (extended + cs).hexToByteArray().encodeCrockford32() +} + +fun ECKeyPair.toStxAddress(sPrefix: Boolean = false): String { val sha256 = toHexPublicKey64().hexToByteArray().sha256() val hash160 = sha256.digestRipemd160() val extended = "b0${hash160.toNoPrefixHexString()}" val cs = checksum("16${hash160.toNoPrefixHexString()}") - return (extended + cs).hexToByteArray().encodeCrockford32() + val prefix = if(sPrefix) "S" else "" + return prefix + (extended + cs).hexToByteArray().encodeCrockford32() } -fun ECKeyPair.toTestNetStxAddress() : String { +fun ECKeyPair.toTestNetStxAddress(sPrefix: Boolean = false) : String { val sha256 = toHexPublicKey64().hexToByteArray().sha256() val hash160 = sha256.digestRipemd160() val extended = "d0${hash160.toNoPrefixHexString()}" val cs = checksum("1a${hash160.toNoPrefixHexString()}") - return (extended + cs).hexToByteArray().encodeCrockford32() + val prefix = if(sPrefix) "S" else "" + return prefix + (extended + cs).hexToByteArray().encodeCrockford32() } fun String.toBtcAddress(): String { diff --git a/blockstack-sdk/src/test/java/org/blockstack/android/sdk/extensions/AddressesTest.kt b/blockstack-sdk/src/test/java/org/blockstack/android/sdk/extensions/AddressesTest.kt index 6aea3a5a..7656ad83 100644 --- a/blockstack-sdk/src/test/java/org/blockstack/android/sdk/extensions/AddressesTest.kt +++ b/blockstack-sdk/src/test/java/org/blockstack/android/sdk/extensions/AddressesTest.kt @@ -37,6 +37,7 @@ class AddressesTest { Assert.assertEquals(PRIVATE_KEY, keys.keyPair.privateKey.key.toHexStringNoPrefix()) Assert.assertEquals(BTC_ADDRESS_MAINNET, keys.keyPair.toBtcAddress()) Assert.assertEquals(STX_ADDRESS_MAINNET, "S${keys.keyPair.toStxAddress()}") + Assert.assertEquals(STX_ADDRESS_MAINNET, keys.keyPair.toStxAddress(true)) } @Test @@ -46,6 +47,7 @@ class AddressesTest { // Act Assert Assert.assertEquals(STX_ADDRESS_TESTNET, "S${keys.keyPair.toTestNetStxAddress()}") + Assert.assertEquals(STX_ADDRESS_TESTNET, keys.keyPair.toTestNetStxAddress(true)) } diff --git a/example/src/main/java/org/blockstack/android/MainActivity.kt b/example/src/main/java/org/blockstack/android/MainActivity.kt index 47c3efd6..3f1887c6 100644 --- a/example/src/main/java/org/blockstack/android/MainActivity.kt +++ b/example/src/main/java/org/blockstack/android/MainActivity.kt @@ -57,6 +57,7 @@ class MainActivity : AppCompatActivity() { blockstack = Blockstack() _blockstackSession = BlockstackSession(sessionStore, config, blockstack = blockstack) blockstackSignIn = BlockstackSignIn(sessionStore, config, appDetails) + //TODO: change here network = Network("https://core.blockstack.org") signInButton.isEnabled = true getUserAppFileUrlButton.isEnabled = true @@ -186,8 +187,8 @@ class MainActivity : AppCompatActivity() { } getStringFileFromUserButton.setOnClickListener { - - val zoneFileLookupUrl = URL("https://core.blockstack.org/v1/names") + //TODO: change here + val zoneFileLookupUrl = URL("https://stacks-node-api.stacks.co/v1/names") fileFromUserContentsTextView.text = "Downloading file from other user..." lifecycleScope.launch { val profile = blockstack.lookupProfile(username, zoneFileLookupURL = zoneFileLookupUrl) @@ -225,6 +226,7 @@ class MainActivity : AppCompatActivity() { getUserAppFileUrlButton.setOnClickListener { _ -> getUserAppFileUrlText.text = "Getting url ..." + //TODO: change here val zoneFileLookupUrl = "https://core.blockstack.org/v1/names" lifecycleScope.launch { val it = blockstack.getUserAppFileUrl(textFileName, username, "https://flamboyant-darwin-d11c17.netlify.app", zoneFileLookupUrl) From 567fb9f5715ba1fc4dbead6dcc6d8d48ad7edf55 Mon Sep 17 00:00:00 2001 From: FilipeA Date: Wed, 21 Jul 2021 16:11:58 +0100 Subject: [PATCH 2/3] updated: bloco.io PR feedbacks (#4) --- .../org/blockstack/android/sdk/Blockstack.kt | 22 ++++++------------- .../android/sdk/BlockstackSession.kt | 7 ++++-- .../java/org/blockstack/android/sdk/DIDs.kt | 2 +- .../org/blockstack/android/MainActivity.kt | 4 +--- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt index 05bcd5b3..1f8eba17 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/Blockstack.kt @@ -99,8 +99,8 @@ class Blockstack(private val callFactory: Call.Factory = OkHttpClient(), "" }, "profile_url" to null, - "hubUrl" to "https://hub.blockstack.org", //TODO: here is what? - "blockstackAPIUrl" to "https://core.blockstack.org", //TODO: here is what? + "hubUrl" to "https://hub.blockstack.org", + "blockstackAPIUrl" to DEFAULT_CORE_API_ENDPOINT, "associationToken" to null, "version" to VERSION ) @@ -536,21 +536,13 @@ class Blockstack(private val callFactory: Call.Factory = OkHttpClient(), val uncompressedBtcAddress = issuerPublicKey.toBtcAddress() val uncompressedStxAddress = issuerPublicKey.toStxAddress(true) - if (publicKeyOrAddress == issuerPublicKey) { - // pass - } else { - when (publicKeyOrAddress) { - uncompressedBtcAddress -> { /* Pass */} - uncompressedStxAddress -> { /* Pass */} - else -> { - throw Error("Token issuer public key does not match the verifying value") - } - } - } - + if (publicKeyOrAddress == issuerPublicKey) { + // pass + } else if (publicKeyOrAddress != uncompressedBtcAddress && publicKeyOrAddress != uncompressedStxAddress) { + throw Error("Token issuer public key does not match the verifying value") + } return ProfileToken(tokenTripleToJSON(decodedToken)) - } private fun tokenTripleToJSON(decodedToken: Triple): JSONObject { diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt index 62e53ae2..318c090f 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/BlockstackSession.kt @@ -92,8 +92,11 @@ class BlockstackSession(private val sessionStore: ISessionStore, private val app } suspend fun handleUnencryptedSignIn(authResponse: String): Result { - //TODO: change here - val nameLookupUrl = sessionStore.sessionData.json.optString("core-node", "stacks-node-api.stacks.co") + + val nameLookupUrl = sessionStore.sessionData.json.optString( + "core-node", + DEFAULT_CORE_API_ENDPOINT.replace("https://", "") + ) val tokenTriple = blockstack.decodeToken(authResponse) val tokenPayload = tokenTriple.second diff --git a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt index 105c9563..349c68b0 100644 --- a/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt +++ b/blockstack-sdk/src/main/java/org/blockstack/android/sdk/DIDs.kt @@ -20,7 +20,7 @@ class DIDs { }else if (didType == "stx-addr") { return did.split(':')[2] } else { - return null + return null } } diff --git a/example/src/main/java/org/blockstack/android/MainActivity.kt b/example/src/main/java/org/blockstack/android/MainActivity.kt index 3f1887c6..9deaaabc 100644 --- a/example/src/main/java/org/blockstack/android/MainActivity.kt +++ b/example/src/main/java/org/blockstack/android/MainActivity.kt @@ -187,7 +187,6 @@ class MainActivity : AppCompatActivity() { } getStringFileFromUserButton.setOnClickListener { - //TODO: change here val zoneFileLookupUrl = URL("https://stacks-node-api.stacks.co/v1/names") fileFromUserContentsTextView.text = "Downloading file from other user..." lifecycleScope.launch { @@ -226,8 +225,7 @@ class MainActivity : AppCompatActivity() { getUserAppFileUrlButton.setOnClickListener { _ -> getUserAppFileUrlText.text = "Getting url ..." - //TODO: change here - val zoneFileLookupUrl = "https://core.blockstack.org/v1/names" + val zoneFileLookupUrl = DEFAULT_CORE_API_ENDPOINT + "v1/names" lifecycleScope.launch { val it = blockstack.getUserAppFileUrl(textFileName, username, "https://flamboyant-darwin-d11c17.netlify.app", zoneFileLookupUrl) withContext(Dispatchers.Main) { From 2584226c88dd61c4a7d9328caa36d8f2f5a0951d Mon Sep 17 00:00:00 2001 From: FilipeA Date: Wed, 21 Jul 2021 16:39:54 +0100 Subject: [PATCH 3/3] updated: removed todo: (new api does not have all methods, and some response types are different even in the V1 version) --- example/src/main/java/org/blockstack/android/MainActivity.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/example/src/main/java/org/blockstack/android/MainActivity.kt b/example/src/main/java/org/blockstack/android/MainActivity.kt index 9deaaabc..57081e85 100644 --- a/example/src/main/java/org/blockstack/android/MainActivity.kt +++ b/example/src/main/java/org/blockstack/android/MainActivity.kt @@ -57,7 +57,6 @@ class MainActivity : AppCompatActivity() { blockstack = Blockstack() _blockstackSession = BlockstackSession(sessionStore, config, blockstack = blockstack) blockstackSignIn = BlockstackSignIn(sessionStore, config, appDetails) - //TODO: change here network = Network("https://core.blockstack.org") signInButton.isEnabled = true getUserAppFileUrlButton.isEnabled = true