> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polygon.technology/llms.txt
> Use this file to discover all available pages before exploring further.

# Sign and verify with Swift

> Sign and verify EVM or Solana messages, and work with EIP-712 typed data.

Signing produces a signature without preparing or submitting a transaction. Signing and verification require an active wallet session.

## Sign and verify a message

```swift theme={null}
let message = "Approve login for example.com"

let signature = try await omsWallet.wallet.signMessage(
    network: .polygonAmoy,
    message: message
)

if let walletAddress = omsWallet.wallet.walletAddress {
    let isValid = try await omsWallet.wallet.isValidMessageSignature(
        network: .polygonAmoy,
        walletAddress: walletAddress,
        message: message,
        signature: signature
    )

    print("Valid:", isValid)
}
```

`signMessage` returns a hex-encoded signature. Verification returns `Bool`.

## Sign and verify a Solana message

For a selected Solana wallet, use the Solana-specific methods. Off-chain messages do not take a network because they are not cluster-specific.

```swift theme={null}
let message = "Approve login for example.com"
let signature = try await omsWallet.wallet.signSolanaMessage(message: message)

if let walletAddress = omsWallet.wallet.walletAddress {
    let isValid = try await omsWallet.wallet.isValidSolanaMessageSignature(
        walletAddress: walletAddress,
        message: message,
        signature: signature
    )

    print("Valid:", isValid)
}
```

## Sign and verify typed data

Represent EIP-712 typed data with public `JSONValue` cases.

```swift theme={null}
let typedData: JSONValue = .object([
    "domain": .object([
        "name": .string("Example"),
        "version": .string("1"),
        "chainId": .integer(80002)
    ]),
    "types": .object([
        "Message": .array([
            .object([
                "name": .string("contents"),
                "type": .string("string")
            ])
        ])
    ]),
    "primaryType": .string("Message"),
    "message": .object([
        "contents": .string("Approve login for example.com")
    ])
])

let signature = try await omsWallet.wallet.signTypedData(
    network: .polygonAmoy,
    typedData: typedData
)

if let walletAddress = omsWallet.wallet.walletAddress {
    let isValid = try await omsWallet.wallet.isValidTypedDataSignature(
        network: .polygonAmoy,
        walletAddress: walletAddress,
        typedData: typedData,
        signature: signature
    )

    print("Valid:", isValid)
}
```

Use the same network and exact payload for signing and verification.

## Understand verification context

Both verification methods accept an explicit `walletAddress`, so you can choose the address checked by the service. They still use the active wallet ID as OMS verification context. The Swift SDK does not expose these methods as unauthenticated verification for arbitrary wallets.

If no wallet is active, signing and verification throw a session error. Indexer reads are different: they accept any address without an active wallet session.
