Updated on 2026-08-14
This commit is contained in:
parent
e79c46caf4
commit
1f27edeb70
16 changed files with 294 additions and 81 deletions
|
|
@ -4,6 +4,7 @@ import com.tangem.datasource.api.auth.models.request.AuthApiRequest
|
|||
import com.tangem.datasource.api.auth.models.request.NonceApiRequest
|
||||
import com.tangem.datasource.api.auth.models.request.RefreshApiRequest
|
||||
import com.tangem.datasource.api.auth.models.request.RegisterApiRequest
|
||||
import com.tangem.datasource.api.auth.models.request.WalletRegistrationRequest
|
||||
import com.tangem.datasource.api.auth.models.response.NonceApiResponse
|
||||
import com.tangem.datasource.api.auth.models.response.TokenApiResponse
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
|
|
@ -30,8 +31,7 @@ interface AuthApi {
|
|||
* session token pair. Called once per app install.
|
||||
*/
|
||||
@POST("api/v1/auth/register")
|
||||
@RequiresDpopProof
|
||||
suspend fun register(@Body request: RegisterApiRequest): ApiResponse<TokenApiResponse>
|
||||
suspend fun registerDevice(@Body request: RegisterApiRequest): ApiResponse<TokenApiResponse>
|
||||
|
||||
/**
|
||||
* Request authentication nonce.
|
||||
|
|
@ -61,4 +61,23 @@ interface AuthApi {
|
|||
@POST("api/v1/auth/refresh")
|
||||
@RequiresDpopProof
|
||||
suspend fun refresh(@Body request: RefreshApiRequest): ApiResponse<TokenApiResponse>
|
||||
|
||||
/**
|
||||
* Request wallet registration nonce.
|
||||
*
|
||||
* Generates a nonce bound to the device public key for the wallet registration flow.
|
||||
*/
|
||||
@POST("api/v1/auth/nonce/wallet")
|
||||
suspend fun requestWalletNonce(@Body request: NonceApiRequest): ApiResponse<NonceApiResponse>
|
||||
|
||||
/**
|
||||
* Register a wallet.
|
||||
*
|
||||
* Binds a new wallet to an already-registered device. When a card signature is provided the
|
||||
* wallet is bound as COLD (card-backed); otherwise it is registered as a MOBILE (hot) wallet.
|
||||
* Returns refreshed session tokens reflecting the updated wallet list.
|
||||
*/
|
||||
@POST("api/v1/auth/wallet")
|
||||
@RequiresDpopProof
|
||||
suspend fun registerWallet(@Body request: WalletRegistrationRequest): ApiResponse<TokenApiResponse>
|
||||
}
|
||||
|
|
@ -10,17 +10,17 @@ import com.squareup.moshi.JsonClass
|
|||
@JsonClass(generateAdapter = true)
|
||||
data class DeviceMetadata(
|
||||
/** Device hardware model (e.g. `iPhone 15 Pro`). */
|
||||
@Json(name = "deviceModel") val deviceModel: String?,
|
||||
@Json(name = "deviceModel") val deviceModel: String,
|
||||
/** Operating system (`android` / `ios`). */
|
||||
@Json(name = "os") val os: String,
|
||||
/** OS version string (e.g. `17.4.1`). */
|
||||
@Json(name = "osVersion") val osVersion: String?,
|
||||
@Json(name = "osVersion") val osVersion: String,
|
||||
/** Application version (e.g. `5.8.0`). */
|
||||
@Json(name = "appVersion") val appVersion: String?,
|
||||
@Json(name = "appVersion") val appVersion: String,
|
||||
/** User-Agent header (e.g. `Tangem/5.8.0 (iPhone; iOS 17.4.1; Scale/3.00)`). */
|
||||
@Json(name = "userAgent") val userAgent: String?,
|
||||
@Json(name = "userAgent") val userAgent: String,
|
||||
/** Client locale (e.g. `en-US`). */
|
||||
@Json(name = "locale") val locale: String?,
|
||||
@Json(name = "locale") val locale: String,
|
||||
/** Client timezone (e.g. `Europe/Moscow`). */
|
||||
@Json(name = "timezone") val timezone: String?,
|
||||
@Json(name = "timezone") val timezone: String,
|
||||
)
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.tangem.datasource.api.auth.models.request
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Wallet registration request — binds a new wallet to an already-registered device.
|
||||
*
|
||||
* When [cardSignature] (and the accompanying [cardSignatureSalt] / [walletStatus]) is provided the
|
||||
* wallet is bound as COLD (card-backed); otherwise it is registered as a MOBILE (hot) wallet.
|
||||
* Mirrors the `WalletRegistrationRequest` schema in the backend OpenAPI contract.
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class WalletRegistrationRequest(
|
||||
/** Deciphered nonce value from `/api/v1/auth/nonce/wallet`. */
|
||||
@Json(name = "nonce") val nonce: String,
|
||||
/**
|
||||
* Wallet identifier — Base64-encoded
|
||||
* `HMAC-SHA256(key = SHA-256(walletPublicKey), data = "UserWalletID")`.
|
||||
*/
|
||||
@Json(name = "walletId") val walletId: String,
|
||||
/**
|
||||
* Base64-encoded secp256k1 RSV signature (65 bytes) over `sha256(nonce || walletSignatureSalt)`.
|
||||
* The server recovers `walletPublicKey` from this signature.
|
||||
*/
|
||||
@Json(name = "walletSignature") val walletSignature: String,
|
||||
/** Base64-encoded salt used in the wallet signature hash. */
|
||||
@Json(name = "walletSignatureSalt") val walletSignatureSalt: String,
|
||||
/**
|
||||
* Base64-encoded secp256k1 RSV signature (65 bytes) over
|
||||
* `sha256(walletPublicKey || nonce || cardSignatureSalt || walletStatus)`. Required for
|
||||
* cold-wallet registration; `null` for mobile (hot) wallets.
|
||||
*/
|
||||
@Json(name = "cardSignature") val cardSignature: String?,
|
||||
/** Base64-encoded salt used in the card signature hash. Required for cold-wallet registration. */
|
||||
@Json(name = "cardSignatureSalt") val cardSignatureSalt: String?,
|
||||
/**
|
||||
* Base64-encoded single byte describing wallet provenance on the card
|
||||
* (`0x82` = generated on card, `0xC2` = SEED imported). Required for cold-wallet registration.
|
||||
*/
|
||||
@Json(name = "walletStatus") val walletStatus: String?,
|
||||
/** Platform attestation token (Play Integrity / App Attest). */
|
||||
@Json(name = "attestationToken") val attestationToken: String?,
|
||||
/** Client-reported device metadata. */
|
||||
@Json(name = "metadata") val metadata: DeviceMetadata,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue