Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ app/*.apk
*.log

fearless.jks
fearless-upload.jks
/buildSrc/build
46 changes: 42 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//file:noinspection GroovyImplicitNullArgumentCall
import com.github.triplet.gradle.androidpublisher.ReleaseStatus
import java.util.Properties

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
Expand All @@ -12,6 +13,20 @@ apply plugin: 'com.google.firebase.appdistribution'
apply plugin: "com.github.triplet.play"
apply from: "../scripts/versions.gradle"

def localKeystoreProperties = new Properties()
def localKeystorePropertiesFile = rootProject.file("local.properties")
if (localKeystorePropertiesFile.exists()) {
localKeystoreProperties.load(localKeystorePropertiesFile.newDataInputStream())
}

def envOrLocalProp = { envKey, propKey ->
def envValue = System.getenv(envKey)
if (envValue != null && !envValue.trim().isEmpty()) {
return envValue
}
return localKeystoreProperties.getProperty(propKey)
}

android {
compileSdk rootProject.compileSdkVersion
defaultConfig {
Expand All @@ -24,10 +39,31 @@ android {
}
signingConfigs {
ci {
storeFile file(System.env.CI_KEYSTORE_PATH ?: "../debug-keystore.jks")
storePassword System.env.CI_KEYSTORE_PASS ?: "00000000"
keyAlias System.env.CI_KEYSTORE_KEY_ALIAS ?: "fearless"
keyPassword System.env.CI_KEYSTORE_KEY_PASS ?: "00000000"
def keystorePath = envOrLocalProp("CI_KEYSTORE_PATH", "ANDROID_RELEASE_KEYSTORE_PATH")
def releaseKeystore = rootProject.file("fearless-upload.jks")
def debugKeystore = rootProject.file("debug-keystore.jks")

def resolvedStoreFile = null
if (keystorePath) {
def candidate = file(keystorePath)
if (candidate.exists()) {
resolvedStoreFile = candidate
} else {
throw new GradleException("Provided CI keystore path does not exist: ${candidate.absolutePath}")
}
}
if (resolvedStoreFile == null && releaseKeystore.exists()) {
resolvedStoreFile = releaseKeystore
}
if (resolvedStoreFile == null) {
resolvedStoreFile = debugKeystore
Comment thread
WRRicht3r marked this conversation as resolved.
}

storeFile resolvedStoreFile

storePassword envOrLocalProp("CI_KEYSTORE_PASS", "ANDROID_RELEASE_KEYSTORE_PASSWORD") ?: "00000000"
keyAlias envOrLocalProp("CI_KEYSTORE_KEY_ALIAS", "ANDROID_RELEASE_KEYSTORE_ALIAS") ?: "fearless"
keyPassword envOrLocalProp("CI_KEYSTORE_KEY_PASS", "ANDROID_RELEASE_KEYSTORE_KEY_PASSWORD") ?: "00000000"
}
debug {
storeFile file("../debug-keystore.jks")
Expand Down Expand Up @@ -145,6 +181,8 @@ android {
packagingOptions {
resources.excludes.add("META-INF/**/*")
resources.excludes.add("META-INF/*")
resources.excludes.add("META-INF/services/org.w3c.dom.DOMImplementationSourceList")
resources.excludes.add("META-INF/services/org.xml.sax.driver")
}
}

Expand Down
1 change: 1 addition & 0 deletions common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ android {
buildConfigField "String", "WALLET_CONNECT_PROJECT_ID", readSecretInQuotes("FL_WALLET_CONNECT_PROJECT_ID")
buildConfigField "String", "FL_DWELLIR_API_KEY", readSecretInQuotes("FL_DWELLIR_API_KEY")
buildConfigField "String", "FL_ANDROID_TON_API_KEY", readSecretInQuotes("FL_ANDROID_TON_API_KEY")
buildConfigField "String", "TON_INDEXER_URL", readSecretInQuotes("FL_ANDROID_TON_INDEXER_URL")

buildConfigField("String", "DAPPS_URL", "\"https://raw.githubusercontent.com/soramitsu/shared-features-utils/refs/heads/develop-free/appConfigs/dapps.json\"")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,41 @@ import retrofit2.http.Query
import retrofit2.http.Url

interface TonApi {
@GET()//"/v2/accounts/{account_id}")
@GET
suspend fun getAccountData(@Url url: String): TonAccountData

@GET()//"//v2/accounts/{account_id}/jettons")
@GET
suspend fun getJettonBalances(@Url url: String, @Query("currencies") currencies: List<String>?): JettonsBalances

@GET
suspend fun getIndexerBalances(@Url url: String): TonIndexerBalancesResponse

@GET
suspend fun getIndexerState(@Url url: String): TonIndexerStateResponse

@POST
suspend fun runIndexerGetMethod(
@Url url: String,
@Body body: TonIndexerRunGetMethodRequest
): TonIndexerRunGetMethodResponse

@GET
suspend fun getIndexerTransactions(
@Url url: String,
@Query("page") page: Int? = null,
@Query("cursor_lt") cursorLt: String? = null,
@Query("cursor_hash") cursorHash: String? = null
): TonIndexerTransactionsResponse

@GET
suspend fun getIndexerJettonTransferPayload(@Url url: String): JettonTransferPayloadRemote

@POST
suspend fun callIndexerJsonRpc(
@Url url: String,
@Body body: TonIndexerJsonRpcRequest
): TonIndexerJsonRpcResponse

@GET
suspend fun getRequest(@Url url: String): String

Expand All @@ -37,10 +66,7 @@ interface TonApi {
): AccountEvents

@GET
suspend fun getManifest(
@Url url: String,
// @Header("Connection") value: String = "close"
): TonAppManifest
suspend fun getManifest(@Url url: String): TonAppManifest

@POST
suspend fun tonconnectSend(
Expand All @@ -53,4 +79,4 @@ interface TonApi {

@GET("https://tonapi.io/v2/rates?tokens=TON")
fun getTonCoinPrice(@Query("currencies") currencies: List<String>?): RatesResponse
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package jp.co.soramitsu.common.data.network.ton

import com.google.gson.JsonElement
import com.google.gson.annotations.SerializedName

data class TonIndexerJsonRpcRequest(
@SerializedName("id")
val id: Int = 1,
@SerializedName("jsonrpc")
val jsonrpc: String = "2.0",
@SerializedName("method")
val method: String,
@SerializedName("params")
val params: Map<String, Any?> = emptyMap()
)

data class TonIndexerJsonRpcResponse(
@SerializedName("id")
val id: JsonElement? = null,
@SerializedName("jsonrpc")
val jsonrpc: String? = null,
@SerializedName("result")
val result: JsonElement? = null,
@SerializedName("error")
val error: TonIndexerJsonRpcError? = null
)

data class TonIndexerJsonRpcError(
@SerializedName("code")
val code: Int? = null,
@SerializedName("message")
val message: String? = null,
@SerializedName("data")
val data: JsonElement? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package jp.co.soramitsu.common.data.network.ton

import com.google.gson.annotations.SerializedName

data class TonIndexerBalancesResponse(
@SerializedName("address")
val address: String,
@SerializedName("ton_raw")
val tonRaw: String,
@SerializedName("ton")
val ton: String? = null,
@SerializedName("assets")
val assets: List<TonIndexerAssetBalance> = emptyList(),
@SerializedName("confirmed")
val confirmed: Boolean = true,
@SerializedName("updated_at")
val updatedAt: Long = 0,
@SerializedName("network")
val network: String? = null
)

data class TonIndexerAssetBalance(
@SerializedName("kind")
val kind: String?,
@SerializedName("symbol")
val symbol: String? = null,
@SerializedName("address")
val address: String? = null,
@SerializedName("wallet")
val wallet: String? = null,
@SerializedName("balance_raw")
val balanceRaw: String,
@SerializedName("balance")
val balance: String,
@SerializedName("decimals")
val decimals: Int
)

data class TonIndexerStateResponse(
@SerializedName("address")
val address: String,
@SerializedName("last_tx_lt")
val lastTxLt: String? = null,
@SerializedName("last_tx_hash")
val lastTxHash: String? = null,
@SerializedName("last_seen_utime")
val lastSeenUtime: Long? = null,
@SerializedName("last_confirmed_seqno")
val lastConfirmedSeqno: Int? = null,
@SerializedName("account_state")
val accountState: String? = null,
@SerializedName("code_boc")
val codeBoc: String? = null,
@SerializedName("data_boc")
val dataBoc: String? = null,
@SerializedName("network")
val network: String? = null
)

data class TonIndexerRunGetMethodRequest(
@SerializedName("address")
val address: String,
@SerializedName("method")
val method: String,
@SerializedName("stack")
val stack: List<List<Any?>> = emptyList()
)

data class TonIndexerRunGetMethodResponse(
@SerializedName("exit_code")
val exitCode: Int,
@SerializedName("gas_used")
val gasUsed: Int,
@SerializedName("stack")
val stack: List<List<Any?>> = emptyList()
)

data class TonIndexerTransactionsResponse(
@SerializedName("page")
val page: Int = 1,
@SerializedName("page_size")
val pageSize: Int = 0,
@SerializedName("total_txs")
val totalTxs: Int = 0,
@SerializedName("total_pages")
val totalPages: Int? = null,
@SerializedName("total_pages_min")
val totalPagesMin: Int = 0,
@SerializedName("history_complete")
val historyComplete: Boolean = false,
@SerializedName("txs")
val txs: List<TonIndexerTransaction> = emptyList(),
@SerializedName("network")
val network: String? = null
)

data class TonIndexerTransaction(
@SerializedName("txId")
val txId: String? = null,
@SerializedName("utime")
val utime: Long = 0,
@SerializedName("status")
val status: String? = null,
@SerializedName("reason")
val reason: String? = null,
@SerializedName("txType")
val txType: String? = null,
@SerializedName("inSource")
val inSource: String? = null,
@SerializedName("inValue")
val inValue: String? = null,
@SerializedName("outCount")
val outCount: Int = 0,
@SerializedName("detail")
val detail: TonIndexerTransactionDetail? = null,
@SerializedName("actions")
val actions: List<Any?> = emptyList(),
@SerializedName("lt")
val lt: String,
@SerializedName("hash")
val hash: String = "",
@SerializedName("inMessage")
val inMessage: TonIndexerMessage? = null,
@SerializedName("outMessages")
val outMessages: List<TonIndexerMessage>? = null,
@SerializedName("fee")
val fee: String? = null,
@SerializedName("total_fees")
val totalFees: String? = null
)

data class TonIndexerTransactionDetail(
@SerializedName("kind")
val kind: String? = null,
@SerializedName("asset")
val asset: String? = null,
@SerializedName("amount")
val amount: String? = null,
@SerializedName("payToken")
val payToken: String? = null,
@SerializedName("receiveToken")
val receiveToken: String? = null,
@SerializedName("payAmount")
val payAmount: String? = null,
@SerializedName("receiveAmount")
val receiveAmount: String? = null
)

data class TonIndexerMessage(
@SerializedName("source")
val source: String? = null,
@SerializedName("destination")
val destination: String? = null,
@SerializedName("value")
val value: String? = null,
@SerializedName("op")
val op: Int? = null,
@SerializedName("body")
val body: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ class EncryptedPreferencesImpl(
}

override fun getDecryptedString(field: String): String? {
val encryptedString = preferences.getString(field)
return encryptedString?.let { encryptionUtil.decrypt(it) }
val encryptedString = preferences.getString(field) ?: return null
val decrypted = encryptionUtil.decrypt(encryptedString)

if (decrypted.isNotEmpty() && !encryptionUtil.isModernCiphertext(encryptedString)) {
preferences.putString(field, encryptionUtil.encrypt(decrypted))
}

return decrypted
}

override fun hasKey(field: String): Boolean {
Expand Down
Loading