Build secure, scalable, and feature-rich digital wallet applications with our comprehensive financial API. From P2P transfers to Stripe integration, from secure E2EE transactions to real-time balance management.
allgram Wallet provides enterprise-level security, FIPS 140-2 compliance, and seamless integration with popular payment systems. Perfect for businesses, developers, and organizations requiring professional financial solutions.
E2EE, P2P, FIPS 140-2 compliant
WebSocket, P2P, instant transactions
REST API, SDKs, comprehensive docs
Build robust digital wallet applications with Node.js and Express.js. Our comprehensive API provides real-time financial operations, WebSocket support, and enterprise-grade security features. Perfect for building scalable backend services and real-time wallet applications.
// allgram Wallet Node.js Integration Example
const express = require('express');
const WebSocket = require('ws');
const crypto = require('crypto');
const axios = require('axios');
class allgramWalletClient {
constructor(apiKey, baseUrl = 'https://api.allgram.best') {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
this.ws = null;
this.transactions = new Map();
this.balance = '0.00';
}
// Initialize WebSocket connection for real-time updates
async connectWebSocket() {
try {
this.ws = new WebSocket(`wss://api.allgram.best/ws/wallet/`);
this.ws.on('open', () => {
console.log('✅ WebSocket connected to wallet service');
// Authenticate with API key
this.ws.send(JSON.stringify({
type: 'auth',
api_key: this.apiKey
}));
});
this.ws.on('message', (data) => {
this.handleWebSocketMessage(JSON.parse(data));
});
this.ws.on('error', (error) => {
console.error('WebSocket error:', error);
this.reconnect();
});
} catch (error) {
console.error('Failed to connect WebSocket:', error);
}
}
// Get wallet balance
async getWalletBalance() {
try {
const response = await axios.get(`${this.baseUrl}/wallet/v1/balance/`, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
if (response.status === 200) {
this.balance = response.data.amount;
console.log(`✅ Wallet balance: ${this.balance} AGC`);
return this.balance;
}
} catch (error) {
console.error('Failed to get wallet balance:', error.response?.data || error.message);
throw error;
}
}
// Get wallet transactions
async getWalletTransactions(sortBy = 'transaction_datetime', isSorted = 0, isReverseSorted = 0) {
try {
const response = await axios.get(`${this.baseUrl}/wallet/v1/transactions/`, {
params: {
sort_by: sortBy,
is_sorted: isSorted,
is_reverse_sorted: isReverseSorted
},
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
if (response.status === 200) {
const transactions = response.data;
transactions.forEach(tx => {
this.transactions.set(tx.id, tx);
});
console.log(`✅ Retrieved ${transactions.length} transactions`);
return transactions;
}
} catch (error) {
console.error('Failed to get transactions:', error.response?.data || error.message);
throw error;
}
}
// Create a new transaction (transfer funds)
async createTransaction(recipientUsername, amount, description = 'Personal funds transfer') {
try {
const response = await axios.post(`${this.baseUrl}/wallet/v1/transaction/create/`, {
user_id: recipientUsername,
amount: amount.toString(),
transaction_description: description
}, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
if (response.status === 200) {
const transaction = response.data;
this.transactions.set(transaction.id, transaction);
console.log(`✅ Transaction created: ${amount} AGC to @${recipientUsername}`);
return transaction;
}
} catch (error) {
console.error('Failed to create transaction:', error.response?.data || error.message);
throw error;
}
}
// Refill wallet through Stripe
async refillWallet(amountUSD) {
try {
const amountInCents = Math.round(amountUSD * 100);
const response = await axios.post(`${this.baseUrl}/wallet/v1/refill/payment-intent/`, {
amount: amountInCents
}, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
if (response.status === 200) {
const paymentIntent = response.data;
console.log(`✅ Payment intent created: ${amountUSD} USD`);
return paymentIntent;
}
} catch (error) {
console.error('Failed to create payment intent:', error.response?.data || error.message);
throw error;
}
}
// Handle WebSocket messages
handleWebSocketMessage(message) {
if (message.type === 'balance_update') {
this.handleBalanceUpdate(message);
} else if (message.type === 'transaction_update') {
this.handleTransactionUpdate(message);
} else if (message.type === 'payment_status') {
this.handlePaymentStatus(message);
}
}
// Handle balance updates
handleBalanceUpdate(message) {
this.balance = message.new_balance;
console.log(`💰 Balance updated: ${this.balance} AGC`);
// Emit event for UI updates
this.emit('balanceUpdated', this.balance);
}
// Handle transaction updates
handleTransactionUpdate(message) {
const transaction = message.transaction;
this.transactions.set(transaction.id, transaction);
console.log(`💸 Transaction updated: ${transaction.amount} AGC`);
// Emit event for UI updates
this.emit('transactionUpdated', transaction);
}
// Handle payment status updates
handlePaymentStatus(message) {
console.log(`💳 Payment status: ${message.status}`);
if (message.status === 'succeeded') {
this.getWalletBalance(); // Refresh balance
}
}
// Reconnection logic
reconnect() {
setTimeout(() => {
console.log('🔄 Attempting to reconnect...');
this.connectWebSocket();
}, 5000);
}
// Utility method to emit events
emit(event, data) {
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
this.ws.send(JSON.stringify({
type: 'event',
event: event,
data: data
}));
}
}
}
// Usage example
const walletClient = new allgramWalletClient('your-api-key-here');
// Initialize connection
walletClient.connectWebSocket();
// Get initial balance
walletClient.getWalletBalance();
// Create a transaction
walletClient.createTransaction('recipient_user', 50.25, 'Payment for services')
.then(transaction => {
console.log('Transaction created successfully:', transaction);
})
.catch(error => {
console.error('Failed to create transaction:', error);
});
// Refill wallet
walletClient.refillWallet(100.00)
.then(paymentIntent => {
console.log('Payment intent created:', paymentIntent);
// Integrate with Stripe frontend here
})
.catch(error => {
console.error('Failed to create payment intent:', error);
});
Our Node.js integration provides enterprise-grade wallet capabilities with minimal setup. Built on proven technologies like Express.js and WebSocket, it offers exceptional performance and reliability for production financial applications.
Build native iOS wallet applications with Swift and SwiftUI. Our iOS SDK provides seamless integration with UIKit and SwiftUI, real-time financial operations, and secure E2EE implementation. Perfect for creating professional iOS wallet applications with modern design patterns.
// allgram Wallet Swift iOS Integration Example
import SwiftUI
import Combine
import CryptoKit
// MARK: - Wallet Models
struct WalletBalance: Codable, Identifiable {
let id = UUID()
let amount: String
enum CodingKeys: String, CodingKey {
case amount
}
}
struct Transaction: Codable, Identifiable {
let id: String
let senderId: String
let userId: String
let amount: String
let transactionDatetime: String
let transactionStatus: Int
let transactionDescription: String
enum CodingKeys: String, CodingKey {
case id
case senderId = "sender_id"
case userId = "user_id"
case amount
case transactionDatetime = "transaction_datetime"
case transactionStatus = "transaction_status"
case transactionDescription = "transaction_description"
}
}
struct PaymentIntent: Codable {
let id: String
let clientSecret: String
let amount: Int
enum CodingKeys: String, CodingKey {
case id
case clientSecret = "client_secret"
case amount
}
}
// MARK: - Wallet Service
class allgramWalletService: ObservableObject {
@Published var balance: String = "0.00"
@Published var transactions: [Transaction] = []
@Published var isConnected = false
private var webSocket: URLSessionWebSocketTask?
private var cancellables = Set<AnyCancellable>()
private let baseURL = "https://api.allgram.best"
private let apiKey: String
init(apiKey: String) {
self.apiKey = apiKey
setupWebSocket()
}
// MARK: - WebSocket Setup
private func setupWebSocket() {
guard let url = URL(string: "wss://api.allgram.best/ws/wallet/") else { return }
let session = URLSession(configuration: .default)
webSocket = session.webSocketTask(with: url)
webSocket?.resume()
// Authenticate
let authMessage = WebSocketMessage(type: "auth", apiKey: apiKey)
sendWebSocketMessage(authMessage)
// Start receiving messages
receiveMessage()
}
// MARK: - Wallet Operations
func getWalletBalance() async throws -> String {
guard let url = URL(string: "\(baseURL)/wallet/v1/balance/") else {
throw WalletError.invalidURL
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw WalletError.invalidResponse
}
let balanceResponse = try JSONDecoder().decode(WalletBalance.self, from: data)
DispatchQueue.main.async {
self.balance = balanceResponse.amount
}
return balanceResponse.amount
}
func getWalletTransactions(sortBy: String = "transaction_datetime",
isSorted: Int = 0,
isReverseSorted: Int = 0) async throws -> [Transaction] {
var components = URLComponents(string: "\(baseURL)/wallet/v1/transactions/")!
components.queryItems = [
URLQueryItem(name: "sort_by", value: sortBy),
URLQueryItem(name: "is_sorted", value: String(isSorted)),
URLQueryItem(name: "is_reverse_sorted", value: String(isReverseSorted))
]
guard let url = components.url else {
throw WalletError.invalidURL
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw WalletError.invalidResponse
}
let transactions = try JSONDecoder().decode([Transaction].self, from: data)
DispatchQueue.main.async {
self.transactions = transactions
}
return transactions
}
func createTransaction(recipientUsername: String,
amount: String,
description: String = "Personal funds transfer") async throws -> Transaction {
guard let url = URL(string: "\(baseURL)/wallet/v1/transaction/create/") else {
throw WalletError.invalidURL
}
let transactionData = [
"user_id": recipientUsername,
"amount": amount,
"transaction_description": description
]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONSerialization.data(withJSONObject: transactionData)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw WalletError.invalidResponse
}
let transaction = try JSONDecoder().decode(Transaction.self, from: data)
return transaction
}
func refillWallet(amountUSD: Double) async throws -> PaymentIntent {
guard let url = URL(string: "\(baseURL)/wallet/v1/refill/payment-intent/") else {
throw WalletError.invalidURL
}
let amountInCents = Int(amountUSD * 100)
let refillData = ["amount": amountInCents]
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONSerialization.data(withJSONObject: refillData)
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw WalletError.invalidResponse
}
let paymentIntent = try JSONDecoder().decode(PaymentIntent.self, from: data)
return paymentIntent
}
// MARK: - WebSocket Communication
private func sendWebSocketMessage(_ message: WebSocketMessage) {
guard let data = try? JSONEncoder().encode(message) else { return }
webSocket?.send(.data(data)) { error in
if let error = error {
print("WebSocket send error: \(error)")
}
}
}
private func receiveMessage() {
webSocket?.receive { [weak self] result in
switch result {
case .success(let message):
self?.handleWebSocketMessage(message)
self?.receiveMessage() // Continue receiving
case .failure(let error):
print("WebSocket receive error: \(error)")
self?.reconnect()
}
}
}
private func handleWebSocketMessage(_ message: URLSessionWebSocketTask.Message) {
switch message {
case .data(let data):
if let walletMessage = try? JSONDecoder().decode(WalletWebSocketMessage.self, from: data) {
DispatchQueue.main.async {
self.processWalletMessage(walletMessage)
}
}
case .string(let string):
if let data = string.data(using: .utf8),
let walletMessage = try? JSONDecoder().decode(WalletWebSocketMessage.self, from: data) {
DispatchQueue.main.async {
self.processWalletMessage(walletMessage)
}
}
@unknown default:
break
}
}
private func processWalletMessage(_ message: WalletWebSocketMessage) {
switch message.type {
case "balance_update":
if let newBalance = message.data?["new_balance"] as? String {
self.balance = newBalance
}
case "transaction_update":
if let transactionData = message.data?["transaction"] as? [String: Any],
let transaction = try? JSONSerialization.data(withJSONObject: transactionData),
let transaction = try? JSONDecoder().decode(Transaction.self, from: transaction) {
self.updateTransaction(transaction)
}
case "payment_status":
if let status = message.data?["status"] as? String, status == "succeeded" {
Task {
try? await self.getWalletBalance()
}
}
default:
break
}
}
private func updateTransaction(_ transaction: Transaction) {
if let index = transactions.firstIndex(where: { $0.id == transaction.id }) {
transactions[index] = transaction
} else {
transactions.append(transaction)
}
}
private func reconnect() {
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
self.setupWebSocket()
}
}
}
// MARK: - Supporting Types
struct WebSocketMessage: Codable {
let type: String
let apiKey: String
enum CodingKeys: String, CodingKey {
case type
case apiKey = "api_key"
}
}
struct WalletWebSocketMessage: Codable {
let type: String
let data: [String: Any]?
enum CodingKeys: String, CodingKey {
case type
case data
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
type = try container.decode(String.self, forKey: .type)
data = try container.decodeIfPresent([String: Any].self, forKey: .data)
}
}
enum WalletError: Error {
case invalidURL
case invalidResponse
case networkError
}
// MARK: - SwiftUI View Example
struct WalletView: View {
@StateObject private var walletService = allgramWalletService(apiKey: "your-api-key-here")
@State private var recipientUsername = ""
@State private var amount = ""
@State private var description = ""
var body: some View {
NavigationView {
VStack(spacing: 20) {
// Balance Display
VStack {
Text("Wallet Balance")
.font(.headline)
.foregroundColor(.secondary)
Text("\(walletService.balance) AGC")
.font(.largeTitle)
.fontWeight(.bold)
.foregroundColor(.primary)
}
.padding()
.background(Color(.systemGray6))
.cornerRadius(12)
// Transfer Form
VStack(alignment: .leading, spacing: 12) {
Text("Transfer Funds")
.font(.headline)
TextField("Recipient Username", text: $recipientUsername)
.textFieldStyle(RoundedBorderTextFieldStyle())
TextField("Amount (AGC)", text: $amount)
.textFieldStyle(RoundedBorderTextFieldStyle())
.keyboardType(.decimalPad)
TextField("Description", text: $description)
.textFieldStyle(RoundedBorderTextFieldStyle())
Button("Send Transaction") {
Task {
do {
let transaction = try await walletService.createTransaction(
recipientUsername: recipientUsername,
amount: amount,
description: description.isEmpty ? "Personal funds transfer" : description
)
print("Transaction created: \(transaction)")
// Clear form
recipientUsername = ""
amount = ""
description = ""
} catch {
print("Transaction failed: \(error)")
}
}
}
.buttonStyle(.borderedProminent)
.disabled(recipientUsername.isEmpty || amount.isEmpty)
}
.padding()
.background(Color(.systemGray6))
.cornerRadius(12)
Spacer()
}
.padding()
.navigationTitle("allgram Wallet")
.task {
do {
try await walletService.getWalletBalance()
try await walletService.getWalletTransactions()
} catch {
print("Failed to load wallet data: \(error)")
}
}
}
}
}
Our Swift integration provides native iOS wallet capabilities with modern SwiftUI patterns. Built on Apple's latest frameworks, it offers exceptional performance and seamless integration with iOS ecosystem.
Build native Android wallet applications with Kotlin and Jetpack Compose. Our Android SDK provides seamless integration with modern Android development tools, real-time financial operations, and secure E2EE implementation. Perfect for creating professional Android wallet applications with Material Design 3.
// allgram Wallet Kotlin Android Integration Example
package com.allgram.wallet
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.util.concurrent.TimeUnit
// MARK: - Data Models
data class WalletBalance(
val amount: String
)
data class Transaction(
val id: String,
val senderId: String,
val userId: String,
val amount: String,
val transactionDatetime: String,
val transactionStatus: Int,
val transactionDescription: String
)
data class PaymentIntent(
val id: String,
val clientSecret: String,
val amount: Int
)
// MARK: - Wallet Service
class allgramWalletService(private val apiKey: String) {
private val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build()
private val baseURL = "https://api.allgram.best"
suspend fun getWalletBalance(): Result<String> = runCatching {
val request = Request.Builder()
.url("$baseURL/wallet/v1/balance/")
.addHeader("Authorization", "Bearer $apiKey")
.addHeader("Content-Type", "application/json")
.get()
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw Exception("HTTP ${response.code}: ${response.message}")
}
val responseBody = response.body?.string() ?: throw Exception("Empty response")
val jsonObject = JSONObject(responseBody)
jsonObject.getString("amount")
}
}
suspend fun getWalletTransactions(
sortBy: String = "transaction_datetime",
isSorted: Int = 0,
isReverseSorted: Int = 0
): Result<List<Transaction>> = runCatching {
val url = "$baseURL/wallet/v1/transactions/?" +
"sort_by=$sortBy&" +
"is_sorted=$isSorted&" +
"is_reverse_sorted=$isReverseSorted"
val request = Request.Builder()
.url(url)
.addHeader("Authorization", "Bearer $apiKey")
.addHeader("Content-Type", "application/json")
.get()
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw Exception("HTTP ${response.code}: ${response.message}")
}
val responseBody = response.body?.string() ?: throw Exception("Empty response")
// Parse JSON array to List<Transaction>
// Implementation depends on your JSON parsing library
emptyList() // Placeholder
}
}
suspend fun createTransaction(
recipientUsername: String,
amount: String,
description: String = "Personal funds transfer"
): Result<Transaction> = runCatching {
val jsonBody = JSONObject().apply {
put("user_id", recipientUsername)
put("amount", amount)
put("transaction_description", description)
}
val requestBody = jsonBody.toString()
.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$baseURL/wallet/v1/transaction/create/")
.addHeader("Authorization", "Bearer $apiKey")
.addHeader("Content-Type", "application/json")
.post(requestBody)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw Exception("HTTP ${response.code}: ${response.message}")
}
val responseBody = response.body?.string() ?: throw Exception("Empty response")
// Parse JSON to Transaction
// Implementation depends on your JSON parsing library
Transaction("", "", "", "", "", 0, "") // Placeholder
}
}
suspend fun refillWallet(amountUSD: Double): Result<PaymentIntent> = runCatching {
val amountInCents = (amountUSD * 100).toInt()
val jsonBody = JSONObject().apply {
put("amount", amountInCents)
}
val requestBody = jsonBody.toString()
.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("$baseURL/wallet/v1/refill/payment-intent/")
.addHeader("Authorization", "Bearer $apiKey")
.addHeader("Content-Type", "application/json")
.post(requestBody)
.build()
client.newCall(request).execute().use { response ->
if (!response.isSuccessful) {
throw Exception("HTTP ${response.code}: ${response.message}")
}
val responseBody = response.body?.string() ?: throw Exception("Empty response")
val jsonObject = JSONObject(responseBody)
PaymentIntent(
id = jsonObject.getString("id"),
clientSecret = jsonObject.getString("client_secret"),
amount = jsonObject.getInt("amount")
)
}
}
}
// MARK: - ViewModel
class WalletViewModel : ViewModel() {
private val walletService = allgramWalletService("your-api-key-here")
private val _balance = MutableStateFlow("0.00")
val balance: StateFlow<String> = _balance.asStateFlow()
private val _transactions = MutableStateFlow<List<Transaction>>(emptyList())
val transactions: StateFlow<List<Transaction>> = _transactions.asStateFlow()
private val _isLoading = MutableStateFlow(false)
val isLoading: StateFlow<Boolean> = _isLoading.asStateFlow()
init {
loadWalletData()
}
fun loadWalletData() {
viewModelScope.launch {
_isLoading.value = true
try {
walletService.getWalletBalance().onSuccess { balance ->
_balance.value = balance
}
walletService.getWalletTransactions().onSuccess { transactions ->
_transactions.value = transactions
}
} catch (e: Exception) {
// Handle error
} finally {
_isLoading.value = false
}
}
}
fun createTransaction(
recipientUsername: String,
amount: String,
description: String
) {
viewModelScope.launch {
try {
walletService.createTransaction(recipientUsername, amount, description)
.onSuccess { transaction ->
// Handle success
loadWalletData() // Refresh data
}
.onFailure { error ->
// Handle error
}
} catch (e: Exception) {
// Handle error
}
}
}
fun refillWallet(amountUSD: Double) {
viewModelScope.launch {
try {
walletService.refillWallet(amountUSD)
.onSuccess { paymentIntent ->
// Handle payment intent
// Integrate with Stripe or other payment provider
}
.onFailure { error ->
// Handle error
}
} catch (e: Exception) {
// Handle error
}
}
}
}
// MARK: - Compose UI
@Composable
fun WalletScreen(
viewModel: WalletViewModel = viewModel()
) {
val balance by viewModel.balance.collectAsState()
val transactions by viewModel.transactions.collectAsState()
val isLoading by viewModel.isLoading.collectAsState()
var recipientUsername by remember { mutableStateOf("") }
var amount by remember { mutableStateOf("") }
var description by remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// Balance Card
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Wallet Balance",
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = "$balance AGC",
style = MaterialTheme.typography.headlineLarge,
color = MaterialTheme.colorScheme.primary
)
}
}
// Transfer Form
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "Transfer Funds",
style = MaterialTheme.typography.titleMedium
)
OutlinedTextField(
value = recipientUsername,
onValueChange = { recipientUsername = it },
label = { Text("Recipient Username") },
modifier = Modifier.fillMaxWidth()
)
OutlinedTextField(
value = amount,
onValueChange = { amount = it },
label = { Text("Amount (AGC)") },
modifier = Modifier.fillMaxWidth()
)
OutlinedTextField(
value = description,
onValueChange = { description = it },
label = { Text("Description") },
modifier = Modifier.fillMaxWidth()
)
Button(
onClick = {
viewModel.createTransaction(
recipientUsername,
amount,
if (description.isEmpty()) "Personal funds transfer" else description
)
// Clear form
recipientUsername = ""
amount = ""
description = ""
},
modifier = Modifier.fillMaxWidth(),
enabled = recipientUsername.isNotEmpty() && amount.isNotEmpty()
) {
Text("Send Transaction")
}
}
}
// Transactions List
if (transactions.isNotEmpty()) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Text(
text = "Recent Transactions",
style = MaterialTheme.typography.titleMedium
)
Spacer(modifier = Modifier.height(8.dp))
transactions.forEach { transaction ->
TransactionItem(transaction = transaction)
Spacer(modifier = Modifier.height(8.dp))
}
}
}
}
if (isLoading) {
CircularProgressIndicator(
modifier = Modifier.align(Alignment.CenterHorizontally)
)
}
}
}
@Composable
fun TransactionItem(transaction: Transaction) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(
text = transaction.transactionDescription,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = transaction.transactionDatetime,
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
Text(
text = "${if (transaction.senderId == "current_user") "-" else "+"}${transaction.amount} AGC",
style = MaterialTheme.typography.bodyMedium,
color = if (transaction.senderId == "current_user")
MaterialTheme.colorScheme.error
else
MaterialTheme.colorScheme.primary
)
}
}
// MARK: - Main Activity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
WalletScreen()
}
}
}
}
}
Our Kotlin integration provides native Android wallet capabilities with modern development patterns. Built on Jetpack Compose and Coroutines, it offers exceptional performance and seamless integration with Android ecosystem.
Ready to take your wallet integration to the next level? Explore our comprehensive resources and advanced features to build enterprise-grade financial applications with allgram.
Learn about our enterprise security features, FIPS 140-2 compliance, and P2P architecture.
Learn More →Discover advanced techniques for optimizing wallet performance and scalability.
Learn More →Join our developer community for support, updates, and collaboration.
Join Community →