-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9dab89a
commit 4ab7b8c
Showing
82 changed files
with
2,245 additions
and
224 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
apps/wallet/api/src/main/java/com/tonapps/wallet/api/entity/ConfigResponseEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.tonapps.wallet.api.entity | ||
|
||
import android.os.Parcelable | ||
import kotlinx.parcelize.Parcelize | ||
import org.json.JSONObject | ||
|
||
@Parcelize | ||
data class ConfigResponseEntity( | ||
val mainnet: ConfigEntity, | ||
val testnet: ConfigEntity, | ||
): Parcelable { | ||
constructor(json: JSONObject, debug: Boolean) : this( | ||
mainnet = ConfigEntity(json.getJSONObject("mainnet"), debug), | ||
testnet = ConfigEntity(json.getJSONObject("testnet"), debug) | ||
) | ||
} |
52 changes: 52 additions & 0 deletions
52
apps/wallet/api/src/main/java/com/tonapps/wallet/api/holders/HoldersAccountEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.tonapps.wallet.api.holders | ||
|
||
import android.os.Parcelable | ||
import com.squareup.moshi.Json | ||
import com.squareup.moshi.Moshi | ||
import kotlinx.parcelize.Parcelize | ||
|
||
@Parcelize | ||
data class HoldersAccountEntity( | ||
@Json(name = "id") val id: String, | ||
@Json(name = "accountIndex") val accountIndex: Int, | ||
@Json(name = "address") val address: String?, | ||
@Json(name = "name") val name: String?, | ||
@Json(name = "seed") val seed: String?, | ||
@Json(name = "state") val state: String, | ||
@Json(name = "balance") val balance: String, | ||
@Json(name = "tzOffset") val tzOffset: Int, | ||
@Json(name = "contract") val contract: String, | ||
@Json(name = "partner") val partner: String, | ||
@Json(name = "network") val network: String, | ||
@Json(name = "ownerAddress") val ownerAddress: String, | ||
@Json(name = "cryptoCurrency") val cryptoCurrency: CryptoCurrency?, | ||
@Json(name = "limits") val limits: AccountLimits?, | ||
@Json(name = "cards") val cards: List<HoldersCardEntity> | ||
): Parcelable { | ||
@Parcelize | ||
data class CryptoCurrency( | ||
val decimals: Int, | ||
val ticker: String, | ||
val tokenContract: String? | ||
): Parcelable | ||
|
||
@Parcelize | ||
data class AccountLimits( | ||
val tzOffset: Int, | ||
val dailyDeadline: Int, | ||
val dailySpent: String, | ||
val monthlyDeadline: Int, | ||
val monthlySpent: String, | ||
val monthly: String, | ||
val daily: String, | ||
val onetime: String | ||
): Parcelable | ||
|
||
fun toJSON(): String { | ||
val moshi = Moshi.Builder() | ||
.add(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory()) | ||
.build() | ||
val adapter = moshi.adapter(HoldersAccountEntity::class.java) | ||
return adapter.toJson(this) | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
apps/wallet/api/src/main/java/com/tonapps/wallet/api/holders/HoldersAccountTokenResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.tonapps.wallet.api.holders | ||
|
||
import com.squareup.moshi.Json | ||
|
||
data class HoldersAccountTokenResponse( | ||
@Json(name = "ok") val ok: Boolean, | ||
@Json(name = "token") val token: String | ||
) |
10 changes: 10 additions & 0 deletions
10
apps/wallet/api/src/main/java/com/tonapps/wallet/api/holders/HoldersAccountsResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.tonapps.wallet.api.holders | ||
|
||
import com.squareup.moshi.Json | ||
|
||
data class HoldersAccountsResponse( | ||
@Json(name = "ok") val ok: Boolean, | ||
@Json(name = "list") val list: List<HoldersAccountEntity>, | ||
@Json(name = "prepaidCards") val prepaidCards: List<HoldersCardEntity>, | ||
@Json(name = "error") val error: String? | ||
) |
157 changes: 157 additions & 0 deletions
157
apps/wallet/api/src/main/java/com/tonapps/wallet/api/holders/HoldersApi.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
package com.tonapps.wallet.api.holders | ||
|
||
import com.squareup.moshi.JsonAdapter | ||
import com.squareup.moshi.Moshi | ||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory | ||
import com.tonapps.blockchain.ton.contract.BaseWalletContract | ||
import com.tonapps.blockchain.ton.extensions.base64 | ||
import com.tonapps.blockchain.ton.extensions.hex | ||
import com.tonapps.blockchain.ton.extensions.toAccountId | ||
import com.tonapps.blockchain.ton.proof.TONProof | ||
import com.tonapps.wallet.api.entity.ConfigEntity | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.withContext | ||
import okhttp3.MediaType.Companion.toMediaType | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.RequestBody.Companion.toRequestBody | ||
|
||
class HoldersApi( | ||
private val okHttpClient: OkHttpClient, | ||
private val getConfig: (testnet: Boolean) -> ConfigEntity | ||
) { | ||
|
||
private fun endpoint(path: String, testnet: Boolean): String { | ||
val host = | ||
if (testnet) "https://card-staging.whales-api.com" else getConfig(false).holdersServiceEndpoint | ||
return host + path | ||
} | ||
|
||
private suspend inline fun <reified T> post( | ||
path: String, | ||
testnet: Boolean, | ||
payload: Map<String, Any> | ||
): T = withContext(Dispatchers.IO) { | ||
val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build() | ||
val jsonAdapter = moshi.adapter(Map::class.java) | ||
val jsonPayload = jsonAdapter.toJson(payload) | ||
val requestBody = jsonPayload.toRequestBody("application/json".toMediaType()) | ||
|
||
val url = endpoint(path, testnet) | ||
|
||
val request = Request.Builder() | ||
.url(url) | ||
.post(requestBody) | ||
.addHeader("Content-Type", "application/json") | ||
.addHeader("Access-Control-Allow-Origin", "*") | ||
.addHeader("Access-Control-Allow-Headers", "*") | ||
.addHeader("Access-Control-Allow-Credentials", "true") | ||
.build() | ||
|
||
val response = okHttpClient.newCall(request).execute() | ||
|
||
if (response.code == 401) { | ||
throw IllegalArgumentException("Unauthorized") | ||
} | ||
|
||
val responseBody = response.body?.string() ?: throw Exception("Empty response body") | ||
val adapter: JsonAdapter<T> = moshi.adapter(T::class.java) | ||
|
||
val parseResult = adapter.fromJson(responseBody) | ||
?: throw IllegalArgumentException("Invalid response") | ||
|
||
parseResult | ||
} | ||
|
||
private fun getNetwork(testnet: Boolean): String { | ||
return if (testnet) "ton-testnet" else "ton-mainnet" | ||
} | ||
|
||
suspend fun fetchAccountsPublic( | ||
address: String, | ||
testnet: Boolean | ||
): List<HoldersAccountEntity> = withContext(Dispatchers.IO) { | ||
val response = post<HoldersPublicAccountsResponse>( | ||
"/v2/public/accounts", testnet, mapOf( | ||
"walletKind" to "tonkeeper", | ||
"network" to getNetwork(testnet), | ||
"address" to address | ||
) | ||
) | ||
|
||
if (!response.ok) { | ||
throw IllegalArgumentException("Error fetching card list: ${response.error}") | ||
} | ||
|
||
response.accounts | ||
} | ||
|
||
suspend fun fetchAccountsList( | ||
token: String, | ||
testnet: Boolean | ||
): HoldersAccountsResponse = withContext(Dispatchers.IO) { | ||
val response = post<HoldersAccountsResponse>( | ||
"/v2/account/list", testnet, mapOf( | ||
"token" to token | ||
) | ||
) | ||
|
||
if (!response.ok) { | ||
throw IllegalArgumentException("Error fetching card list: ${response.error}") | ||
} | ||
|
||
response | ||
} | ||
|
||
suspend fun fetchAccountToken( | ||
contract: BaseWalletContract, | ||
proof: TONProof.Result, | ||
testnet: Boolean | ||
): String = withContext(Dispatchers.IO) { | ||
val payload = mapOf( | ||
"stack" to "ton", | ||
"network" to getNetwork(testnet), | ||
"key" to mapOf( | ||
"kind" to "tonconnect-v2", | ||
"wallet" to "tonkeeper", | ||
"config" to mapOf( | ||
"address" to contract.address.toAccountId(), | ||
"proof" to mapOf( | ||
"timestamp" to proof.timestamp, | ||
"domain" to mapOf( | ||
"lengthBytes" to proof.domain.lengthBytes, | ||
"value" to proof.domain.value | ||
), | ||
"signature" to proof.signature, | ||
"payload" to proof.payload, | ||
"walletStateInit" to contract.stateInitCell().base64(), | ||
"publicKey" to contract.publicKey.hex() | ||
) | ||
) | ||
) | ||
) | ||
|
||
val response = | ||
post<HoldersAccountTokenResponse>("/v2/user/wallet/connect", testnet, payload) | ||
|
||
if (!response.ok) { | ||
throw IllegalArgumentException("Error fetching account token") | ||
} | ||
|
||
response.token | ||
} | ||
|
||
suspend fun fetchUserState(token: String, testnet: Boolean) = withContext(Dispatchers.IO) { | ||
val response = post<HoldersUserState>( | ||
"/v2/user/state", testnet, mapOf( | ||
"token" to token | ||
) | ||
) | ||
|
||
if (!response.ok) { | ||
throw IllegalArgumentException("Error fetching user state") | ||
} | ||
|
||
response.toJSON() | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
apps/wallet/api/src/main/java/com/tonapps/wallet/api/holders/HoldersCardEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.tonapps.wallet.api.holders | ||
|
||
import android.os.Parcelable | ||
import com.squareup.moshi.Json | ||
import com.squareup.moshi.Moshi | ||
import kotlinx.parcelize.Parcelize | ||
|
||
@Parcelize | ||
data class HoldersCardEntity( | ||
@Json(name = "id") val id: String, | ||
@Json(name = "type") val type: String, | ||
@Json(name = "status") val status: String, | ||
@Json(name = "walletId") val walletId: String?, | ||
@Json(name = "fiatCurrency") val fiatCurrency: String, | ||
@Json(name = "fiatBalance") val fiatBalance: String?, | ||
@Json(name = "lastFourDigits") val lastFourDigits: String?, | ||
@Json(name = "productId") val productId: String, | ||
@Json(name = "personalizationCode") val personalizationCode: String, | ||
@Json(name = "seed") val seed: String?, | ||
@Json(name = "updatedAt") val updatedAt: String, | ||
@Json(name = "createdAt") val createdAt: String, | ||
@Json(name = "provider") val provider: String?, | ||
@Json(name = "kind") val kind: String? | ||
): Parcelable { | ||
fun toJSON(): String { | ||
val moshi = Moshi.Builder() | ||
.add(com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory()) | ||
.build() | ||
val adapter = moshi.adapter(HoldersCardEntity::class.java) | ||
return adapter.toJson(this) | ||
} | ||
} |
Oops, something went wrong.