Appearance
Login with an external wallet
Authenticating a user with their Ethereum wallet is a three step process:
Privy allows you to authenticate a user via an Ethereum wallet using Sign in with Ethereum, or SIWE. This is a three step process:
- Generate a Sign-In With Ethereum (SIWE) message
- From a connected wallet, request an EIP-191
personal_sign
signature for the SIWE message. - Send the verified signature to Privy to authenticate the user's wallet
1. Generate a SIWE Message
To generate a SIWE message, call Privy's siwe.generateSiweMessage
method. This returns the SIWE message for the user to sign as a String
or throw an error.
An error could be thrown if the network call fails.
Method definition
swift
func generateSiweMessage(
params: SiweMessageParams,
metadata: WalletLoginMetadata?
) async throws -> String
SiweMessageParams
- set of parameters required to generate the message.
Field | Type | Description |
---|---|---|
appDomain | String | Your app's domain. e.g. "my-domain.com" |
appUri | String | Your apps URI. e.g. "https://my-domain.com" |
chainId | String | EVM Chain ID, e.g. "1" for Ethereum Mainnet |
walletAddress | String | The user's ERC-55 compliant wallet address. |
WalletLoginMetadata
- Optionally, you can pass additional metadata that will be stored with the linked wallet. You can also override these meatdata params when calling loginWithSiwe
in step 3.
Field | Type | Description |
---|---|---|
walletClientType | WalletClientType | An enum specifying the type of wallet used to login. e.g. WalletClientType.metamask |
connectorType | String | A string identifying how wallet was connected. e.g. "wallet_connect" |
Example integration
swift
do {
let params = SiweMessageParams(
appDomain: "my-domain.com",
appUri: "https://my-domain.com",
chainId: "1",
walletAddress: "0x12345..."
)
let metadata = WalletLoginMetadata(
walletClientType: WalletClientType.metamask,
connectorType: "wallet_connect"
)
let siweMessage = try await privy.siwe.generateSiweMessage(params: params, metadata: metadata)
} catch let error {
// An error can be thrown if the network call to generate the message fails,
// or if invalid metadata was passed in.
}
2. Request an EIP191 signature on the message
Using the message returned by generateSiweMessage
, request an EIP-191 personal_sign
signature from the user's connected wallet. You should do this using the library your app uses to connect to external wallets (e.g. the MetaMask iOS SDK or WalletConnect). Once the user successfully signs the message, store the signature in a variable.
3. Verify the SIWE signature
Authenticate the user by passing the user's signature as a String
to Privy's loginWithSiwe
method. Optionally, you can specify additional metadata about the user's wallet as a second optional WalletLoginMetadata
parameter. If omitted, the metadata passed from generateSiweMessage
will be used. If specified, metadata passed in generateSiweMessage
will be overridden.
Method Definition
swift
func loginWithSiwe(
_ signature: String,
metadata: WalletLoginMetadata?
) async throws -> AuthState
Example integration
swift
do {
// Pass signature to privy to authenticate user.
// Omitting metadata because we specified it in step 1.
let authState = try await privy.siwe.loginWithSiwe(signature)
} catch let error {
// An error can be thrown if a successful call to `generateSiweMessage`
// wasn't made prior to call `loginWithSiwe`
}
Tracking SIWE login flow state
You can add provide a listener to receive state updates during the login with SIWE process.
swift
privy.siwe.setSiweFlowStateChangeCallback{ siweFlowState in
switch siweFlowState {
case .initial:
// Starting state
case .generatingMessage:
// SIWE message being created
case .awaitingSignature:
// Waiting for you to pass the signature generated from the personal_sign request
case .submittingSignature:
// Submitted signature to authenticate
case .done:
// Complete
case .error:
// An error has occurred
}
}
That's it! Your user is now authenticated via external wallet.