
Crea una app móvil para acuñar cNFT en menos de 5 minutos
Qué puedes esperar
Este tutorial explica cómo crear una aplicación para Android que acuñe NFT (tokens no fungibles). La idea es permitir que los usuarios capturen imágenes fácilmente y acuñen NFT comprimidos en Solana. Para lograrlo, usaremos la API de acuñación de Helius. Esta API agiliza la acuñación de NFT comprimidos y reduce el código repetitivo, lo que te ahorra mucho tiempo y planificación. Nuestra aplicación para Android estará escrita en Kotlin y Jetpack Compose.
¿Qué son los NFT comprimidos?
Los NFT comprimidos (cNFT) usan compresión de estado y árboles de Merkle concurrentes para reducir los costos de almacenamiento. Los NFT comprimidos son entre 2,400 y 24,000 veces más baratos que sus equivalentes sin comprimir y conservan estructuras idénticas.
Requisitos previos
Antes de comenzar este tutorial, debes tener conocimientos básicos de desarrollo para Android con Kotlin y estar familiarizado con Solana.
Herramientas
- Android Studio: Giraffe | Versión 2022.3.1
- Emulador o dispositivo móvil: Lo usarás para probar la aplicación. Asegúrate de tener instalada una aplicación de billetera compatible con MWA (se recomienda Solfare).
Clave de API
Para usar la API de acuñación de Helius, necesitarás una clave de API. Sigue estos pasos para obtenerla:
- Visita elportal para desarrolladores de Helius.
- Crea una cuenta con tu billetera de Solana o tu cuenta de Google o GitHub.
- Después de iniciar sesión, sigue las indicaciones para generar una clave de API.
- Guarda esta clave de forma segura, ya que la usarás para hacer llamadas a la API durante todo el tutorial.
Creación de la app
Paso 1: Configura el proyecto
Preparamos una base de código inicial para este proyecto.
Para comenzar, sigue estos pasos:
- Accede al paquete inicial en GitHub.
- Crea un fork del repositorio y clónalo en tu entorno local.
Cuando tengas el código en tu entorno local, haz lo siguiente:
- Abre el proyecto en Android Studio.
- Deja que Gradle complete el proceso de compilación.
- Ejecuta el código.
Explora la app inicial para familiarizarte con sus funciones. Observa el botón para conectar la billetera integrado en la app. Este te permite conectarte a cualquier aplicación de billetera compatible con Mobile Wallet Adapter (MWA). Mobile Wallet Adapter (MWA) es una especificación de protocolo para conectar dApps móviles con aplicaciones de billetera móviles. Permite la comunicación para realizar transacciones de Solana y firmar mensajes. Mobile Wallet Adapter admite estas billeteras. También encontrarás el botón "Tomar una foto", que actualmente permite capturar una imagen.
Para almacenar de forma segura la clave de API de Helius en la base de código, abre el archivo local.properties y agrega la clave de API. Este archivo está diseñado específicamente para contener información confidencial y Git lo ignora, lo que protege la confidencialidad de tu clave de API.
api_key=<your-api-key>
Ahora programaremos la lógica para acuñar la imagen capturada como un NFT comprimido (cNFT).
Paso 2: Lógica de acuñación
Nuestro objetivo es integrar el botón "Tomar una foto" con la funcionalidad de la cámara. Esta integración permitirá que los usuarios capturen imágenes y las acuñen como NFT. Incluimos código inicial para abrir la cámara y capturar imágenes. Ahora nos centraremos en crear una función que gestione el proceso de acuñación.
API de acuñación de Helius
Este método acuña un NFT comprimido. Cuando se ejecuta, queda en pausa hasta que se confirme la transacción. Esto puede tardar hasta 60 segundos durante los periodos de mayor actividad de la red. Consulta la documentación para obtener más información.
Primero, ve a java/com/example/hmint/MainViewModel.kt y crea la función mintCNft dentro de la clase MainViewModel:
@HiltViewModel
class MainViewModel @Inject constructor(
private val walletAdapter: MobileWalletAdapter,
private val walletConnectionUseCase: WalletConnectionUseCase,
) : ViewModel() {
// ...
fun mintCNft(imageUri: Uri, nftName: String, user: String) =
viewModelScope.launch {
_state.update {
_state.value.copy(
isLoading = true,
)
}
}
}Iniciaremos una corrutina para gestionar la lógica de acuñación dentro de esta función. Primero obtendremos la clave de API y definiremos las variables necesarias y el requestBody. Más adelante podrás personalizar requestBody para incluir atributos y datos adicionales según tus requisitos:
withContext(viewModelScope.coroutineContext + Dispatchers.IO) {
val apiKey = System.getProperty("api_key") ?: ""
val url = URL("https://mainnet.helius-rpc.com/?api-key=$apiKey")
val mediaType = "application/json".toMediaTypeOrNull()
val requestBody = """
{
"jsonrpc": "2.0",
"id": "helius-test",
"method": "mintCompressedNft",
"params": {
"name": "$nftName",
"symbol": "HM",
"owner": "$user",
"description": "This is a test cNFT minted by hMint app",
"attributes": [
{
"trait_type": "hMint",
"value": "1"
}
],
"imageUrl": "$imageUri",
"sellerFeeBasisPoints": 6900
}
}
""${'"'}.trimIndent()
}Después, crearemos la solicitud e inicializaremos un OkHttpClient:
val body = requestBody.toRequestBody(mediaType)
val request = Request.Builder()
.url(url)
.post(body)
.addHeader("accept", "application/json")
.addHeader("content-type", "application/json")
.build()
val client = OkHttpClient()Antes de invocar el cliente, definamos la respuesta en una clase de datos. Crea un paquete llamado data y, dentro de él, un archivo nuevo llamado NFTResponse.kt para definir la estructura de la respuesta recibida de la llamada a la API.
package com.example.hmint.data
data class NftMintResponse(
val jsonrpc: String,
val id: String,
val result: MintResult
)
data class MintResult(
val signature: String,
val minted: Boolean,
val assetId: String
)Luego, dentro de la clase MainViewModel, agrega a la clase de datos WalletViewState un valor adicional para mintResponse. Actualizaremos este valor cuando recibamos una respuesta:
data class WalletViewState(
// ...
val mintResponse: String = ""
)De vuelta en nuestra función mintCNft, usaremos el cliente para ejecutar la solicitud y gestionar los errores o las respuestas según corresponda. Cuando recibamos una respuesta, usaremos Gson para analizar los datos y convertirlos en la clase de datos NFTMintResponse que creamos antes. Después, actualizaremos el valor de mintResponse según corresponda:
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
// Handle failure
e.printStackTrace()
Log.d(TAG, "NFT Mint Failed")
_state.update {
_state.value.copy(
isLoading = false,
mintResponse = "Mint Failed"
)
}
}
override fun onResponse(call: Call, response: Response) {
if (response.isSuccessful) {
val responseBody = response.body?.string() ?: ""
val gson = Gson()
val nft = gson.fromJson(responseBody, NftMintResponse::class.java)
Log.d(TAG, "NFT Mint Successful: $nft")
_state.update {
_state.value.copy(
isLoading = false,
mintResponse = "Minted Successfully"
)
}
} else {
// Handle non-successful response
Log.d(TAG, "NFT Mint Failed: ${response.code}")
_state.update {
_state.value.copy(
isLoading = false,
mintResponse = "Minted Failed"
)
}
}
}
})En nuestra UI, queremos informar al usuario sobre el resultado de la función de acuñación. Para ello, ve a java/com/example/hmint/composables/MintButton.kt, que contiene el elemento componible con el código de la UI y la lógica para capturar imágenes. Dentro de MintButton, donde declaramos cameraLauncher, llamaremos a nuestra función mintCNft. También debes incluir código para mostrar un Toast cuando se actualice mintResponse.
@Composable
fun MintButton(
mainViewModel: MainViewModel = hiltViewModel()
) {
val cameraLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.TakePicture()) {
// ...
mainViewModel.mintCNft(uri, "hMint", viewState.userAddress)
}
viewState.mintResponse.let { message ->
if(message.isNotEmpty()){
Toast.makeText(LocalContext.current, message, Toast.LENGTH_SHORT).show()
}
}
// ...
}Paso 3: Ejecuta la app
Terminamos la fase de programación, así que ejecutemos la aplicación. Primero conecta tu billetera y luego captura una imagen. Verás cómo la app acuña el NFT por ti sin complicaciones.
Conclusión
¡Bien hecho! Creaste correctamente una aplicación para Android que permite a los usuarios acuñar NFT comprimidos. Gracias a la API de acuñación de Helius, acuñar cNFT nunca había sido tan sencillo: solo requiere una llamada.
¿Qué sigue?
Aún puedes explorar y mejorar muchos aspectos de esta app. Una posible mejora es integrar DAS API. La API Digital Asset Standard (DAS) es una especificación y un sistema de código abierto que ofrece una interfaz unificada para interactuar con activos digitales, incluidos tokens y NFT. Admite varios tipos de activos, como tokens fungibles, NFT estándar y NFT comprimidos. Puedes usar la API para obtener todos los NFT comprimidos acuñados y mostrarlos en tu aplicación. Así ofrecerás a los usuarios una vista integral de sus activos digitales.
Recursos relevantes
Para ampliar tus conocimientos sobre el desarrollo para Android con Jetpack Compose, profundizar en la integración con la blockchain de Solana y la interacción con API, consulta los siguientes recursos:
- Jetpack Compose
- Solana Mobile Adapter en Kotlin
- Inyección de dependencias con Hilt
- OkHttpClient en Android
- Compresión en Solana
- API MINT de Helius
Si necesitas ayuda o soporte, contáctanos en Discord. La base de código completa está disponible en GitHub como referencia adicional.
Artículos relacionados
Suscríbete a Helius
Mantente al día con las novedades del desarrollo en Solana y recibe actualizaciones cuando publiquemos


