> For the complete documentation index, see [llms.txt](/llms.txt).

# Dapp share

## Embedded Wallets infrastructure at a glance[​](#embedded-wallets-infrastructure-at-a-glance "Direct link to Embedded Wallets infrastructure at a glance")

As described in the [Embedded Wallets infrastructure](/embedded-wallets/infrastructure/), to keep Embedded Wallets non-custodial, the private key is split into multiple parts called `shares`. These shares are a part of the offchain multisig, where multiple shares are stored in different places and can be used to reconstruct the private key dynamically in the user's frontend application. Typically, there are 3 shares:

1. **`ShareA` is managed by a sign-in service via node operators:** This share is further split amongst a network of nodes and retrieved via conventional authentication flows.
2. **`ShareB` is stored on the user's device:** Implementation is device and system specific. For example, on mobile devices, the share could be stored in device storage secured via biometrics.
3. **`ShareC` is a recovery share:** An extra share to be kept by the user, possibly kept on a separate device, downloaded or based on user input with enough entropy (such as, password, security questions, hardware device).

Similar to existing 2FA systems, a user needs to prove ownership of at least 2 out of 3 (2/3) shares to retrieve their private key.

## Mobile platform user experience[​](#mobile-platform-user-experience "Direct link to Mobile platform user experience")

The user experience on mobile platforms differs from web platforms. On mobile, the user is redirected to a browser to sign in with their social accounts and then back to the app after authentication. This shifts context between two applications, whereas on web platforms the context remains within the browser only.

For a seamless sign-in flow, Shares `A` and `B` must be reconstructed. `Share B` is managed by the sign-in service and is provided on successful authentication. On web platforms, `Share A` is stored in the browser context. You can still store it in the browser context on mobile devices, but this carries risks; users may delete browser data by mistake. This is a bigger problem on mobile because users don't realize the browser is used to sign in within the app, and clearing browser data can cause sign-in to fail. To address this, Embedded Wallets issues a dapp share, a backup share that you can store directly in your app and use to reconstruct the private key after a successful sign-in.

## Dapp share in iOS[​](#dapp-share-in-ios "Direct link to Dapp share in iOS")

After a successful sign-in, the SDK returns user details to your app.

#### Sample response in iOS[​](#sample-response-in-ios "Direct link to Sample response in iOS")

```
{
  "userInfo": {
    "email": "w3a-heroes@web3auth.com",
    "name": "Web3Auth Heroes",
    "profileImage": "https://lh3.googleusercontent.com/a/Ajjjsdsmdjmnm...",
    "authConnectionId": "torus",
    "userId": "w3a-heroes@web3auth.com",
    "authConnection": "google",
    "groupedAuthConnectionId": "w3a-google-sapphire",
    "dappShare": "", // 24 words of seed phrase will be sent only incase of custom auth connections
    "idToken": "<jwtToken issued by Web3Auth>",
    "oAuthIdToken": "<jwtToken issued by OAuth Provider>", // will be sent only incase of custom auth connections
    "oAuthAccessToken": "<accessToken issued by OAuth Provider>", // will be sent only incase of custom auth connections
    "isMfaEnabled": false // Returns whether the user has enabled MFA or not
  }
}

```

The response includes a `dappShare` field, a 24-word seed phrase that can reconstruct the private key. `dappShare` supplements `Share A` and represents half of the private key. You can store the dapp share in your app's local storage.

During sign-in, the user's social account provides one share, and your app provides the dapp share, removing the need to store a share in the browser context. Pass the stored dapp share value in the `connectTo` call.

note

`dappShare` is only available for custom auth connections, not standard Embedded Wallets auth connections. This ensures your app only has access to the share corresponding to your users' private keys. To use dapp share, you must use the [custom authentication](/embedded-wallets/sdk/ios/advanced/custom-authentication/) feature. Dapp share is only returned to users who have enabled 2FA on their account.

```
try await web3Auth.connectTo(
    loginParams: LoginParams(
        authConnection: selectedAuthConnection,
        dappShare: "<24 words seed phrase>"
    )
)

```

## Example[​](#example "Direct link to Example")

```
import Foundation
import Web3Auth

class ViewModel: ObservableObject {
    var web3Auth: Web3Auth?
    @Published var loggedIn: Bool = false
    @Published var userInfo: Web3AuthUserInfo?
    @Published var isLoading = false
    @Published var navigationTitle: String = ""

    func setup() async {
        guard web3Auth == nil else { return }
        await MainActor.run {
            isLoading = true
            navigationTitle = "Loading"
        }
        web3Auth = try? await Web3Auth(
            options: Web3AuthOptions(
                clientId: "YOUR_WEB3AUTH_CLIENT_ID",
                web3AuthNetwork: .SAPPHIRE_MAINNET,
                redirectUrl: "com.yourapp.bundleid://auth"
            )
        )

        await MainActor.run {
            if self.web3Auth?.web3AuthResponse != nil {
                userInfo = web3Auth?.web3AuthResponse?.userInfo
                loggedIn = true
            }
            isLoading = false
            navigationTitle = loggedIn ? "UserInfo" : "SignIn"
        }
    }

    func login(authConnection: AuthConnection) {
        Task {
            do {
                let result = try await web3Auth?.connectTo(
                    loginParams: LoginParams(
                        // authConnection can be .GOOGLE, .FACEBOOK, .APPLE etc
                        authConnection: authConnection,
                        dappShare: "<24 words seed phrase>"
                    )
                )

                await MainActor.run {
                    userInfo = result?.userInfo
                    loggedIn = true
                }
            } catch {
                print("Error: \(error)")
            }
        }
    }
}

```
