
Crie um app móvel para cunhar cNFTs em menos de 5 minutos
O que esperar
Este tutorial mostra como criar um aplicativo Android para cunhar NFTs (tokens não fungíveis). A ideia é permitir que os usuários capturem imagens facilmente e cunhem NFTs comprimidos na Solana. Para isso, usaremos a Helius Mint API. Essa API acelera a cunhagem de NFTs comprimidos e reduz o código repetitivo, economizando muito tempo e planejamento. Nosso aplicativo Android será desenvolvido em Kotlin e Jetpack Compose.
O que são NFTs comprimidos?
NFTs comprimidos (cNFTs) usam compressão de estado e árvores de Merkle simultâneas para reduzir os custos de armazenamento. NFTs comprimidos são de 2.400 a 24.000 vezes mais baratos que seus equivalentes não comprimidos, mantendo estruturas idênticas.
Pré-requisitos
Antes de começar este tutorial, você deve ter conhecimentos básicos de desenvolvimento Android com Kotlin e familiaridade com a Solana.
Ferramentas
- Android Studio: Giraffe | Versão 2022.3.1
- Emulador ou dispositivo móvel: será usado para testar o aplicativo. Verifique se há um aplicativo de carteira compatível com MWA instalado (recomendamos a Solfare).
Chave de API
Para usar a Helius Mint API, você precisará de uma chave de API. Veja como obtê-la:
- Acesse o Portal do Desenvolvedor da Helius.
- Crie uma conta usando sua carteira Solana ou sua conta do Google ou GitHub.
- Depois de fazer login, siga as instruções para gerar uma chave de API.
- Armazene essa chave com segurança, pois ela será usada para fazer chamadas de API ao longo deste tutorial.
Como criar o app
Etapa 1: configuração do projeto
Preparamos uma base de código inicial para este projeto.
Para começar, siga estas etapas:
- Acesse o projeto inicial no GitHub.
- Faça um fork do repositório e clone-o em seu ambiente local.
Depois de obter o código localmente, faça o seguinte:
- Abra o projeto no Android Studio.
- Aguarde o Gradle concluir o processo de build.
- Execute o código.
Explore o app inicial para conhecer seus recursos. Observe o botão para conectar a carteira integrado ao app. Ele permite que você se conecte a qualquer aplicativo de carteira compatível com o Mobile Wallet Adapter (MWA). O Mobile Wallet Adapter (MWA) é uma especificação de protocolo para conectar dApps móveis a aplicativos móveis de carteira, permitindo a comunicação para transações da Solana e assinatura de mensagens. O Mobile Wallet Adapter oferece suporte a estas carteiras. Você também encontrará o botão "Tirar uma foto", que atualmente permite capturar uma imagem.
Para armazenar com segurança a chave de API da Helius na base de código, acesse o arquivo local.properties e adicione a chave de API. Esse arquivo foi criado especificamente para conter informações confidenciais e é ignorado pelo Git, garantindo a confidencialidade da sua chave de API.
api_key=<your-api-key>
Agora vamos implementar a lógica para cunhar a imagem capturada como um NFT comprimido (cNFT).
Etapa 2: lógica de cunhagem
Nosso objetivo é integrar o botão "Tirar uma foto" à funcionalidade da câmera. Essa integração permitirá que os usuários capturem imagens e as cunhem como NFTs. Fornecemos um código inicial para abrir a câmera e capturar imagens. Agora, nosso foco será criar uma função para gerenciar o processo de cunhagem.
Helius Mint API
Esse método cunha um NFT comprimido. Ao ser executado, ele aguardará até a confirmação da transação, o que pode levar até 60 segundos durante períodos de pico de atividade na rede. Consulte a documentação para saber mais.
Comece acessando java/com/example/hmint/MainViewModel.kt e crie a função mintCNft dentro da classe 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 uma corrotina para processar a lógica de cunhagem dentro dessa função. Primeiro, recuperaremos a chave de API e definiremos as variáveis necessárias e o requestBody. Depois, você poderá personalizar o requestBody para incluir outros atributos e dados de acordo com suas necessidades:
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()
}Em seguida, criaremos a solicitação e inicializaremos um 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 o cliente, vamos definir a resposta em uma classe de dados. Crie um novo pacote chamado data e, dentro dele, um novo arquivo chamado NFTResponse.kt para definir a estrutura da resposta recebida da chamada de 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
)Depois, dentro da classe MainViewModel, adicione à classe de dados WalletViewState um valor para mintResponse. Atualizaremos esse valor quando recebermos uma resposta:
data class WalletViewState(
// ...
val mintResponse: String = ""
)Voltando à nossa função mintCNft, usaremos o cliente para executar a solicitação e tratar adequadamente as falhas ou respostas. Ao receber uma resposta, usaremos Gson para analisar os dados e convertê-los na classe de dados NFTMintResponse criada anteriormente. Depois, atualizaremos o valor de mintResponse de acordo com o resultado:
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"
)
}
}
}
})Na nossa UI, queremos informar ao usuário o resultado da função de cunhagem. Para isso, acesse java/com/example/hmint/composables/MintButton.kt, que contém o composable com o código da UI e a lógica de captura de imagem. Dentro de MintButton, onde declaramos cameraLauncher, chamaremos nossa função mintCNft. Inclua também o código para exibir um Toast quando mintResponse for atualizado.
@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()
}
}
// ...
}Etapa 3: execute o app
Concluímos a etapa de programação. Agora, vamos executar o aplicativo. Primeiro, conecte sua carteira. Em seguida, capture uma imagem e veja o app cunhar o NFT para você de forma simples.
Conclusão
Muito bem! Você desenvolveu com sucesso um aplicativo Android que permite aos usuários cunhar NFTs comprimidos. Graças à Helius Mint API, cunhar cNFTs nunca foi tão simples: basta uma única chamada.
O que vem a seguir?
Ainda há muito o que explorar e aprimorar neste app. Uma dessas melhorias é a integração da DAS API. A API Digital Asset Standard (DAS) é uma especificação e um sistema de código aberto que fornecem uma interface unificada para interagir com ativos digitais, incluindo tokens e NFTs. Ela oferece suporte a vários tipos de ativos, incluindo tokens fungíveis, NFTs padrão e NFTs comprimidos. Com a API, você pode buscar todos os NFTs comprimidos cunhados e exibi-los em seu aplicativo, oferecendo aos usuários uma visão completa de seus ativos digitais.
Recursos relevantes
Para aprofundar seus conhecimentos em desenvolvimento Android com Jetpack Compose, integração com a blockchain Solana e interação com APIs, explore os seguintes recursos:
- Jetpack Compose
- Solana Mobile Adapter em Kotlin
- Injeção de dependência com Hilt
- OkHttpClient no Android
- Compressão na Solana
- Helius MINT API
Se precisar de ajuda ou suporte, fale conosco no Discord. A base de código completa está disponível no GitHub para consulta.
Artigos relacionados
Assine a Helius
Acompanhe as novidades mais recentes do desenvolvimento Solana e receba atualizações quando publicarmos


