Learn how to integrate real-time transaction, address, token, and URL security scanning using Portal’s Android SDK with Blockaid.
Portal’s Android SDK integrates with Blockaid to provide real-time security scanning for transactions, addresses, tokens, and URLs. This integration helps detect malicious activity, phishing attempts, scam tokens, and suspicious interactions before users sign or submit transactions.
Use scanEVMTx to analyze Ethereum transactions before signing or broadcasting them. This method scans EVM transactions for malicious contract interactions, risky approvals, phishing attempts, and other on-chain security threats.
lifecycleScope.launch { try { val transactionData = BlockaidScanEVMTransactionData( from = "0x7C01728004d3F2370C1BBC36a4Ad680fE6FE8729", to = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", data = "0x095ea7b3...", value = "0x0", gas = "0x2dc6c0", gasPrice = "0x2dc6c0", nonce = "0x924" ) val request = BlockaidScanEVMRequest( chain = "eip155:1", data = transactionData, options = listOf(BlockaidScanEVMOption.SIMULATION, BlockaidScanEVMOption.VALIDATION) ) val result = portal.security.blockaid.scanEVMTx(request) result.onSuccess { response -> val rawResponse = response.data?.rawResponse println("Chain: ${rawResponse?.chain}") println("Block: ${rawResponse?.block}") rawResponse?.validation?.let { validation -> println("Validation Status: ${validation.status}") println("Result Type: ${validation.resultType}") if (validation.resultType == "Malicious") { println("⚠️ Transaction flagged as MALICIOUS") } else { println("✅ Transaction appears safe") } } }.onFailure { error -> println("Blockaid EVM Scan failed: ${error.message}") } } catch (e: Exception) { println("Error scanning EVM transaction: ${e.message}") }}
Use scanSolanaTx to analyze Solana transactions before signing. This method detects malicious program invocations, suspicious token movements, and other Solana-specific risks.
Use scanTronTx to analyze Tron transactions before signing. This method detects malicious smart contract interactions, suspicious token movements, and other Tron-specific security risks.
scanTronTx is only supported on Tron mainnet (tron:mainnet). Passing a testnet chain identifier such as tron:shasta or tron:nile returns a failed Result (surfaced through the onFailure callback) without calling Blockaid.
lifecycleScope.launch { try { val transactionData = BlockaidScanTronTransactionData( from = "TKhJBwsH7hvegxrUHW4oHT5t1BUDds2UG4", to = "TMacq4TDUw5q8NFBwmbY4RLXvzvG5JTkvi", data = "0xa9059cbb000000000000000000000041...", value = "0x0" ) val request = BlockaidScanTronRequest( chain = "tron:mainnet", accountAddress = "TKhJBwsH7hvegxrUHW4oHT5t1BUDds2UG4", data = transactionData, options = listOf(BlockaidScanTronOption.SIMULATION, BlockaidScanTronOption.VALIDATION) ) val result = portal.security.blockaid.scanTronTx(request) result.onSuccess { response -> val rawResponse = response.data?.rawResponse println("Chain: ${rawResponse?.chain}") println("Block: ${rawResponse?.block}") rawResponse?.validation?.let { validation -> println("Validation Status: ${validation.status}") println("Result Type: ${validation.resultType}") if (validation.resultType == "Malicious") { println("⚠️ Transaction flagged as MALICIOUS") } else { println("✅ Transaction appears safe") } } }.onFailure { error -> println("Blockaid Tron Scan failed: ${error.message}") } } catch (e: Exception) { println("Error scanning Tron transaction: ${e.message}") }}
The request object maps to the following fields:
Field
Type
Required
Description
chain
String
Yes
Must be tron:mainnet
accountAddress
String?
No
Sender’s Tron address (Base58 format, starts with T)
data.from
String?
No
Sender address (Base58 format)
data.to
String?
No
Recipient address (Base58 format)
data.data
String?
No
Encoded contract call data (hex)
data.value
String?
No
Amount of TRX to transfer (hex)
metadata
BlockaidScanTronMetadata?
No
Dapp or non-dapp context for the transaction
options
List<BlockaidScanTronOption>?
No
Analysis types to run: SIMULATION, VALIDATION, or both
Use scanAddress to analyze a single address for known security risks. This method can be used for both EVM and Solana addresses and detects malicious contracts, compromised wallets, sanctioned addresses, and other flagged entities.
Use scanTokens to analyze multiple tokens in a single request for known security risks. This method detects scam tokens, honeypots, compromised contracts, and other malicious token behavior.
Use scanURL to detect phishing sites and malicious domains before users navigate to them. This method helps protect users from social engineering attacks and malicious off-chain activity.
lifecycleScope.launch { try { val request = BlockaidScanURLRequest( url = "https://app.uniswap.org" ) val result = portal.security.blockaid.scanURL(request) result.onSuccess { response -> val rawResponse = response.data?.rawResponse val status = rawResponse?.status ?: "Unknown" val isMalicious = rawResponse?.isMalicious ?: false println("URL: https://app.uniswap.org") println("Status: $status") println("Is Malicious: $isMalicious") if (status == "hit") { if (isMalicious) { println("⚠️ URL flagged as MALICIOUS") } else { println("✅ URL appears safe") } rawResponse?.maliciousScore?.let { println("Malicious Score: $it") } rawResponse?.isWeb3Site?.let { println("Is Web3 Site: $it") } rawResponse?.isReachable?.let { println("Is Reachable: $it") } } else if (status == "miss") { println("ℹ️ URL not in database (miss)") } }.onFailure { error -> println("Blockaid URL Scan failed: ${error.message}") } } catch (e: Exception) { println("Error scanning URL: ${e.message}") }}
All Blockaid scan methods return a Result type that can be handled using Kotlin’s onSuccess and onFailure callbacks. You should always handle both success and failure cases to ensure robust error handling.
lifecycleScope.launch { try { val result = portal.security.blockaid.scanEVMTx(request) result.onSuccess { response -> // Handle successful response val rawResponse = response.data?.rawResponse // Process the response... }.onFailure { error -> // Handle error println("Blockaid scan failed: ${error.message}") } } catch (e: Exception) { // Handle any unexpected exceptions println("Unexpected error: ${e.message}") }}