Skip to main content
Portal’s iOS SDK provides comprehensive security scanning capabilities through the portal.security.hypernative API. This integration allows you to detect malicious transactions, flagged addresses, compromised tokens, and suspicious URLs before users interact with them.

Overview

The Hypernative integration enables you to:
  • Scan transactions before signing or submission (EVM, EIP-712, Solana)
  • Scan addresses for known malicious actors or compromised contracts
  • Validate tokens to detect scams, honeypots, or security risks
  • Check NFTs for fraudulent collections or suspicious activity
  • Verify URLs to prevent phishing attacks

Prerequisites

Before using Hypernative security scanning, ensure you have:
  • A properly initialized Portal client
  • Hypernative integration enabled in your Portal Dashboard (see Hypernative Integration)

Scanning EVM Transactions

Use scanEVMTx to analyze standard Ethereum transactions before signing or sending. This method scans EVM transactions for malicious contract interactions, suspicious token approvals, and other security risks.
Task {
    do {
        let transaction = ScanEVMTransaction(
            chain: "eip155:1",
            fromAddress: "0x7C01728004d3F2370C1BBC36a4Ad680fE6FE8729",
            toAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
            input: "0x095ea7b300000000000000000000000066ba61be3bab35c0c00038f335850a390b086fe300000000000000000000000000000000000000000fffffffffffffffffffffff",
            value: 0,
            nonce: 2340,
            hash: nil,
            gas: 3000000,
            gasPrice: 3000000,
            maxPriorityFeePerGas: nil,
            maxFeePerGas: nil
        )
        
        let request = ScanEVMRequest(
            transaction: transaction,
            url: nil,
            blockNumber: nil,
            validateNonce: nil,
            showFullFindings: nil,
            policy: nil
        )
        
        let response = try await portal.security.hypernative.scanEVMTx(request: request)
        
        if let rawResponse = response.data?.rawResponse {
            print("Success: \(rawResponse.success)")
            if let data = rawResponse.data {
                print("Recommendation: \(data.recommendation)")
                print("Assessment ID: \(data.assessmentId ?? "N/A")")
                if let findings = data.findings {
                    print("Findings count: \(findings.count)")
                }
            }
        }
    } catch {
        print("Error scanning EVM transaction: \(error)")
    }
}

Scanning EIP-712 Typed Messages

Use scanEip712Tx to analyze typed structured data before signing. This method is critical for detecting malicious permit signatures, phishing attempts, and unauthorized token approvals. EIP-712 defines a standard for hashing and signing typed structured data, commonly used for gasless approvals and off-chain signatures.
Task {
    do {
        let domain = ScanEip712Domain(
            name: "MyToken",
            version: "1",
            chainId: "eip155:1",
            verifyingContract: "0xa0b86991c6218b36c1d19d4a2e9Eb0cE3606eB48",
            salt: nil
        )
        
        let types: [String: [ScanEip712TypeProperty]] = [
            "EIP712Domain": [
                ScanEip712TypeProperty(name: "name", type: "string"),
                ScanEip712TypeProperty(name: "version", type: "string"),
                ScanEip712TypeProperty(name: "chainId", type: "uint256"),
                ScanEip712TypeProperty(name: "verifyingContract", type: "address")
            ],
            "Permit": [
                ScanEip712TypeProperty(name: "owner", type: "address"),
                ScanEip712TypeProperty(name: "spender", type: "address"),
                ScanEip712TypeProperty(name: "value", type: "uint256"),
                ScanEip712TypeProperty(name: "nonce", type: "uint256"),
                ScanEip712TypeProperty(name: "deadline", type: "uint256")
            ]
        ]
        
        let message = ScanEip712TypedData(
            primaryType: "Permit",
            types: types,
            domain: domain,
            message: [
                "owner": AnyCodable("0x7b1363f33b86d16ef7c8d03d11f4394a37d95c36"),
                "spender": AnyCodable("0x67beb4dd770a9c2cbc7133ba428b9eecdcf09186"),
                "value": AnyCodable(3000),
                "nonce": AnyCodable(0),
                "deadline": AnyCodable(50000000000)
            ]
        )
        
        let request = ScanEip712Request(
            walletAddress: "0x7b1363f33b86d16ef7c8d03d11f4394a37d95c36",
            chainId: "eip155:1",
            eip712Message: message,
            showFullFindings: nil,
            policy: nil
        )
        
        let response = try await portal.security.hypernative.scanEip712Tx(request: request)
        
        if let rawResponse = response.data?.rawResponse {
            print("Success: \(rawResponse.success)")
            if let data = rawResponse.data {
                print("Recommendation: \(data.recommendation)")
                print("Assessment ID: \(data.assessmentId ?? "N/A")")
            }
        }
    } catch {
        print("Error scanning EIP-712 transaction: \(error)")
    }
}

Scanning Solana Transactions

Use scanSolanaTx to analyze Solana transactions before signing. This method detects malicious program invocations, suspicious token transfers, and other Solana-specific security risks.
Task {
    do {
        let transaction = ScanSolanaTransaction(
            message: nil,
            signatures: nil,
            rawTransaction: "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=",
            version: "0"
        )
        
        let request = ScanSolanaRequest(
            transaction: transaction,
            url: nil,
            validateRecentBlockHash: nil,
            showFullFindings: true,
            policy: nil
        )
        
        let response = try await portal.security.hypernative.scanSolanaTx(request: request)
        
        if let rawResponse = response.data?.rawResponse {
            print("Success: \(rawResponse.success)")
            if let data = rawResponse.data {
                print("Recommendation: \(data.recommendation)")
                if let findings = data.findings {
                    print("Findings count: \(findings.count)")
                }
            }
        }
    } catch {
        print("Error scanning Solana transaction: \(error)")
    }
}

Scanning Addresses

Use scanAddresses to check multiple addresses for known security risks. This method identifies malicious contracts, compromised wallets, sanctioned addresses, and other flagged entities.
Task {
    do {
        let request = ScanAddressesRequest(
            addresses: [
                "0x31c05d73f2333b5a176cfdbb7c5ef96ec7bb04ac",
                "0x2753a0d37a2ad09be3ccc0afcb650bea8ea57a8f"
            ],
            screenerPolicyId: nil
        )
        
        let response = try await portal.security.hypernative.scanAddresses(request: request)
        
        if let data = response.data {
            for addressResult in data.rawResponse {
                print("Address: \(addressResult.address)")
                print("Recommendation: \(addressResult.recommendation)")
                print("Severity: \(addressResult.severity)")
                print("Flags count: \(addressResult.flags.count)")
            }
        }
    } catch {
        print("Error scanning addresses: \(error)")
    }
}

Scanning NFTs

Use scanNfts to validate NFT collections before displaying or allowing interactions. This method detects fraudulent collections, compromised contracts, and suspicious NFT activity.
Task {
    do {
        let request = ScanNftsRequest(
            nfts: [
                ScanNftsRequestItem(
                    address: "0x5C1B9caA8492585182eD994633e76d744A876548",
                    chain: nil,
                    evmChainId: "eip155:1"
                ),
                ScanNftsRequestItem(
                    address: "0xC2e0cA5FE0b9AbE1B86f3cC0b865448908D20A16",
                    chain: nil,
                    evmChainId: "eip155:1"
                )
            ]
        )
        
        let response = try await portal.security.hypernative.scanNfts(request: request)
        
        if let rawResponse = response.data?.rawResponse {
            print("Success: \(rawResponse.success)")
            if let data = rawResponse.data {
                for nft in data.nfts {
                    print("NFT: \(nft.address)")
                    print("Chain: \(nft.chain ?? "N/A")")
                    print("Accept: \(nft.accept)")
                }
            }
        }
    } catch {
        print("Error scanning NFTs: \(error)")
    }
}

Scanning Tokens

Use scanTokens to validate ERC-20 tokens before allowing swaps, transfers, or approvals. This method detects honeypots, scam tokens, and compromised token contracts.
Task {
    do {
        let request = ScanTokensRequest(
            tokens: [
                ScanTokensRequestItem(
                    address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
                    chain: nil,
                    evmChainId: "eip155:1"
                )
            ]
        )
        
        let response = try await portal.security.hypernative.scanTokens(request: request)
        
        if let rawResponse = response.data?.rawResponse {
            print("Success: \(rawResponse.success)")
            if let data = rawResponse.data {
                for token in data.tokens {
                    print("Token: \(token.address)")
                    print("Chain: \(token.chain ?? "N/A")")
                    if let reputation = token.reputation {
                        print("Reputation: \(reputation.recommendation)")
                    }
                }
            }
        }
    } catch {
        print("Error scanning tokens: \(error)")
    }
}

Scanning URLs

Use scanURL to detect phishing sites and malicious domains before users navigate to them. This method is critical for protecting users from social engineering attacks.
Task {
    do {
        let request = ScanUrlRequest(url: "curve.fi")
        
        let response = try await portal.security.hypernative.scanURL(request: request)
        
        if let rawResponse = response.data?.rawResponse {
            print("Success: \(rawResponse.success)")
            if let data = rawResponse.data {
                let isMalicious = data.isMalicious
                print("Is Malicious: \(isMalicious)")
                if let deepScan = data.deepScanTriggered {
                    print("Deep Scan Triggered: \(deepScan)")
                }
            }
        }
    } catch {
        print("Error scanning URL: \(error)")
    }
}

Next Steps