Documentation Index
Fetch the complete documentation index at: https://docs.portalhq.io/llms.txt
Use this file to discover all available pages before exploring further.
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.
Overview
The Blockaid integration enables you to:
- Scan transactions before signing or submission (EVM, Solana)
- Scan addresses for known malicious actors or compromised contracts
- Validate tokens to detect scams or security risks
- Verify URLs to prevent phishing attacks
Prerequisites
Before using Blockaid security scanning, ensure you have:
- A properly initialized Portal client
- Blockaid integration enabled in your Portal Dashboard
Scanning EVM 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}")
}
}
Scanning Solana Transactions
Use scanSolanaTx to analyze Solana transactions before signing. This method detects malicious program invocations, suspicious token movements, and other Solana-specific risks.
lifecycleScope.launch {
try {
val transactions = listOf(
"AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQADCQkVR3SiiKbW0l4c3NBsEn6+zn1o0YsyypPwN0GUhg4K5HK0Tb5GckDLYW+MsovQASt5EZ3bSH3nluRJAE69H61w0BRUDTrpYQcXosUun6/z2BROkRoH/1bL7KLU9s4lCav6k3ZZgV6qeZFwu4pu89WoIGaqUxG4C93XwVmmDy81v8qBaCSP4/UZfdo3q1bud/W+ixymkH8IMe0laQZYrSx4Uhyxec67hYm1VqLV7JTSSYaC/fm7KvWtZOSRzEFT2gMGRm/lIRcy/+ytunLDm+e8jOW7xfcSayxDmzpAAAAAT4tlY/P4mFG1wDJl0ektVggHiZf73lTlHBVJ3fK0nDoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANG5fPtlMEOI/eXV7aPDlpcdLUKm8L3VoW6k/oJlCNLaBQYABQLARQQABgAJAwYAAAAAAAAABzwACQoLCwgyMzQMNQ0ONjcPEDg5EgETFBUWOhEXGBkaGxwdHh8gISI7IyQlJicCKCkqKywtAwQuLzAxPBFVCg8JAQcHBgYBAAAAAwHwCgYBExUbBgICAAAPAwIAAAYBISMoEQQBGQAPAwIAAAYBLjA2DwMCAAAGAgIAAAAIBgYICAADAQkGCQUFBgACBQAEBwEAAAgCAAUMAgAAADwaAAAAAAAABgAFBGDMBQAEPPm21Wu6wrmHu23/ZFNIumpp+ADooZjd4JQgvjnBxkUJAgEDBqWqCgmmCAUIBwu1tp+gcP/+Ri3C1tRXUbPdgqo6rVsj/qnqC959wTdC/mRARysLz9HS09TW19jZ2tsC1QYsNrdxMcm5Nq5FXZrM0IXpEA+ApFa+pz/JvkLz0+2vnwuztLW2t7i5uru8vgAPvBv8VUeRwDy9yD1NHIH5Ji6ZA+zrmpHejKOz4MP8SwrKy8zNzs/S09TVAdY="
)
val request = BlockaidScanSolanaRequest(
accountAddress = "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
transactions = transactions,
encoding = BlockaidScanSolanaEncoding.BASE64,
chain = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
options = listOf(BlockaidScanSolanaOption.SIMULATION, BlockaidScanSolanaOption.VALIDATION),
method = "signAndSendTransaction"
)
val result = portal.security.blockaid.scanSolanaTx(request)
result.onSuccess { response ->
val rawResponse = response.data?.rawResponse
println("Status: ${rawResponse?.status ?: "Unknown"}")
rawResponse?.result?.validation?.let { validation ->
println("Result Type: ${validation.resultType}")
if (validation.resultType == "Malicious") {
println("⚠️ Transaction flagged as MALICIOUS")
} else {
println("✅ Transaction appears safe")
}
}
}.onFailure { error ->
println("Blockaid Solana Scan failed: ${error.message}")
}
} catch (e: Exception) {
println("Error scanning Solana transaction: ${e.message}")
}
}
Scanning Addresses
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.
EVM Address Scan
lifecycleScope.launch {
try {
val request = BlockaidScanAddressRequest(
address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
chain = "eip155:1"
)
val result = portal.security.blockaid.scanAddress(request)
result.onSuccess { response ->
val rawResponse = response.data?.rawResponse
println("Result Type: ${rawResponse?.resultType}")
rawResponse?.features?.forEach { feature ->
println("Feature: [${feature.type}] ${feature.featureId}: ${feature.description}")
}
}.onFailure { error ->
println("EVM Address Scan failed: ${error.message}")
}
} catch (e: Exception) {
println("Error scanning EVM address: ${e.message}")
}
}
Solana Address Scan
lifecycleScope.launch {
try {
val request = BlockaidScanAddressRequest(
address = "So11111111111111111111111111111111111111112", // Wrapped SOL
chain = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp"
)
val result = portal.security.blockaid.scanAddress(request)
result.onSuccess { response ->
val rawResponse = response.data?.rawResponse
println("Result Type: ${rawResponse?.resultType}")
rawResponse?.features?.forEach { feature ->
println("Feature: [${feature.type}] ${feature.featureId}: ${feature.description}")
}
}.onFailure { error ->
println("Solana Address Scan failed: ${error.message}")
}
} catch (e: Exception) {
println("Error scanning Solana address: ${e.message}")
}
}
Scanning Tokens
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.
lifecycleScope.launch {
try {
val tokens = listOf(
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // USDC
)
val request = BlockaidScanTokensRequest(
chain = "eip155:1",
tokens = tokens
)
val result = portal.security.blockaid.scanTokens(request)
result.onSuccess { response ->
val resultsCount = response.data?.rawResponse?.results?.size ?: 0
println("Results count: $resultsCount")
response.data?.rawResponse?.results?.forEach { (address, tokenResult) ->
println("Token: $address")
println(" Result Type: ${tokenResult.resultType}")
tokenResult.maliciousScore?.let {
println(" Malicious Score: $it")
}
tokenResult.metadata?.let { metadata ->
println(" Name: ${metadata.name ?: "Unknown"}")
println(" Symbol: ${metadata.symbol ?: "Unknown"}")
}
tokenResult.features?.forEach { feature ->
println(" Feature: [${feature.type}] ${feature.featureId}: ${feature.description}")
}
if (tokenResult.resultType == "Malicious") {
println(" ⚠️ Token is MALICIOUS")
}
}
}.onFailure { error ->
println("Blockaid Token Scan failed: ${error.message}")
}
} catch (e: Exception) {
println("Error scanning tokens: ${e.message}")
}
}
Scanning URLs
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}")
}
}
Error Handling
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}")
}
}
Next Steps