Skip to main content
By the end of this guide, you’ll know how to initialize and launch the Mesh SDK embedded in your app, as an overlay, or via Paylinks.
Before you start

Overview

Mesh’s client-side SDKs are supported on the following platforms:
Web
iOS
Android
React Native
Flutter
Those SDKs are home to Link, the Mesh-hosted experience that facilitates the user journey (ie. connecting an account, configuring / previewing / approving transfers, verifying wallet ownership, etc.). You’ll launch an SDK session using a Link Token. This guide will walk you through how to launch an SDK session, including code snippets for each SDK.

Initialize the Mesh SDK

You have 3 options for how to launch Link. You should choose which one fits your UX and other needs the best.

Option 1: Embedded (web SDK only)

Recommended for web implementations Link can be embedded as an iframe into a container within your product surface area. This makes it feel more native to your product by minimizing the “seam” between your app and Mesh. You provide a custom iframe ID in the openLink function of the web SDK.
Image
You’ll include a custom iframe ID in the openLink function when embedding Link into a container in your product (see end of snippet).
renderType
embedded indicates this will not be an overlay, and will slightly modify the UX (importantly, the Mesh SDK nav bar goes away except for the back < button). When embedded, add a custom-iframe-id in the openLink function.
custom-iframe-id (not a parameter, but including here for clarity)
Lets you embed the Mesh SDK directly into a container within your product surface area.
language
You can use the system setting to match their device or browser default, or you can specify a language if you have such a setting in user profiles. See the Multi-language support guide for more info on supported languages.
theme
You can use the system setting to match their device or browser default, or you can specify a theme if you have such a setting in user profiles.
displayFiatCurrency
Link defaults to USD, or you can specify a fiat currency if you have such a setting in user profiles. See the Fiat currency support guide for more info on supported currencies
accessTokens
After users connect an exchange account, Mesh can maintain authorization so that the user doesn’t have to login again. This enables a 1 or 2 click transfer experience for return users. See the Use Mesh’s callback functions guide for more information on consuming Mesh SDK events and handling them with callback functions, and the Supercharge return-users guide to set up a return user experience
linkToken
Link token returned by the Mesh backend.
const connection = createLink({
  renderType: 'embedded', // Indicates Link will be embedded in a container within your web app
  theme: 'system',
  language: 'system',
  displayFiatCurrency: 'USD',
  accessTokens: accessTokens, // See "Supercharge return users" guide
  onIntegrationConnected: payload => {
    // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
    console.log('[MESH LINK integration connected]', payload)
  },
  onTransferFinished: payload => {
    // Called after a transfer flow completes successfully
    console.log('[MESH LINK transfer finished]', payload)
  },
  onExit: () => {
    // Called when Link is closed
    console.log('[MESH LINK exited]')
  },
  onEvent: ev => {
    // Allows you to handle other specific events
    console.log('[MESH LINK event]', ev)
  }
})

connection.openLink(linkToken, 'custom-iframe-id') // Open in your custom iframe
  • The createLink function accepts one argument, a configuration Object typed LinkOptions and returns an Object with two functions, openLink and closeLink. Calling openLink will render the Link UI in an iframe. Calling closeLink will close the already-rendered Link UI. Please note, that the Link UI will close itself once the user finishes their workflow.
Please see the Polish the experience guide for important instructions on how to properly implement this experience.

Option 2: Overlay

Link opens as a modal on top of your product, with a semi-opaque overlay behind it. This focuses the user on the task at hand and minimizes background noise and distractions.
Image
renderType
overlay indicates Mesh will pop up over your product and ensures certain UX elements behave accordingly.
language
You can use the system setting to match their device or browser default, or you can specify a language if you have such a setting in user profiles. See the Multi-language support guide for more info on supported languages.
theme
You can use the system setting to match their device or browser default, or you can specify a theme if you have such a setting in user profiles.
displayFiatCurrency
Link defaults to USD, or you can specify a fiat currency if you have such a setting in user profiles. See the Fiat currency support guide for more info on supported currencies
accessTokens
After users connect an exchange account, Mesh can maintain authorization so that the user doesn’t have to login again. This enables a 1 or 2 click transfer experience for return users. See the Use Mesh’s callback functions guide for more information on consuming Mesh SDK events and handling them with callback functions, and the Supercharge return-users guide to set up a return user experience
linkToken
Link token returned by the Mesh backend.
const connection = createLink({
  renderType: 'overlay', // Opens SDK on top of your web app
  theme: 'system',
  language: 'system',
  displayFiatCurrency: 'USD',
  accessTokens: accessTokens, // See "Supercharge return users" guide
  onIntegrationConnected: payload => {
    // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
    console.log('[MESH LINK integration connected]', payload)
  },
  onTransferFinished: payload => {
    // Called after a transfer flow completes successfully
    console.log('[MESH LINK transfer finished]', payload)
  },
  onExit: () => {
    // Called when Link is closed
    console.log('[MESH LINK exited]')
  },
  onEvent: ev => {
    // Allows you to handle other specific events
    console.log('[MESH LINK event]', ev)
  }
})

connection.openLink(linkToken)
  • The createLink function accepts one argument, a configuration Object typed LinkOptions and returns an Object with two functions, openLink and closeLink. Calling openLink will render the Link UI in an iframe. Calling closeLink will close the already-rendered Link UI. Please note, that the Link UI will close itself once the user finishes their workflow.
language
You can use the system setting to match their device or browser default, or you can specify a language if you have such a setting in user profiles. See the Multi-language support guide for more info on supported languages.
theme
You can use the system setting to match their device or browser default, or you can specify a theme if you have such a setting in user profiles.
displayFiatCurrency
Link defaults to USD, or you can specify a fiat currency if you have such a setting in user profiles. See the Fiat currency support guide for more info on supported currencies
accessTokens
After users connect an exchange account, Mesh can maintain authorization so that the user doesn’t have to login again. This enables a 1 or 2 click transfer experience for return users. See the Use Mesh’s callback functions guide for more information on consuming Mesh SDK events and handling them with callback functions, and the Supercharge return-users guide to set up a return user experience
linkToken
Link token returned by the Mesh backend.
func launchMeshLink(
    linkToken: String,
    viewController: UIViewController,
    accessTokens: [IntegrationAccessToken]? = nil
) {
    var linkHandler: LinkHandler?

    let settings = LinkSettings(
        accessTokens: accessTokens, // See "Supercharge return users" guide
        language: "system",
        displayFiatCurrency: "USD",
        theme: .system
    )

    // Called after a user connects an exchange, wallet, or other integration.
    let onIntegrationConnected: (LinkPayload) -> Void = { linkPayload in
        switch linkPayload {
        case .accessToken(let accessTokenPayload):
            print(accessTokenPayload)
        case .delayedAuth(let delayedAuthPayload):
            print(delayedAuthPayload)
        @unknown default:
            print("unknown LinkPayload")
        }
    }

    // Called after a transfer flow completes successfully or fails.
    let onTransferFinished: (TransferFinishedPayload) -> Void = { transferFinishedPayload in
        switch transferFinishedPayload {
        case .success(let successPayload):
            print(successPayload)
        case .error(let errorPayload):
            print(errorPayload)
        @unknown default:
            print("unknown TransferFinishedPayload")
        }
    }

    // Called throughout the Link flow so you can track user progress.
    let onEvent: ([String: Any]?) -> Void = { payload in
        print("Event: \(payload ?? [:])")
    }

    // Called when the user exits Link
    let onExit: (Bool?) -> Void = { showAlert in
        // showAlert is true when 'x' button is tapped
        // showAlert is false when 'Done' button is tapped on a Transfer Success screen
        if showAlert ?? false {
            // in case a custom alert is implemented, linkHandler?.closeLink() must be called to close Link
            linkHandler?.showExitAlert() // default Exit alert
        } else {
            linkHandler?.closeLink()
        }
    }

    let configuration = LinkConfiguration(
        linkToken: linkToken,
        settings: settings,
        disableDomainWhiteList: false,
        onIntegrationConnected: onIntegrationConnected,
        onTransferFinished: onTransferFinished,
        onEvent: onEvent,
        // onExit is optional, a default alert is shown in case onExit is omitted
        onExit: onExit
    )

    let result = configuration.createHandler()

    // createHandler validates the configuration before Link is presented.
    switch result {
    case .success(let handler):
        linkHandler = handler
        // Present Link from the current UIViewController.
        handler.present(in: viewController)
    case .failure(let error):
        print(error)
    @unknown default:
        print("unknown LinkResult")
    }
}
linkToken
Link token returned by the Mesh backend.
language
You can use the system setting to match their device or browser default, or you can specify a language if you have such a setting in user profiles. See the Multi-language support guide for more info on supported languages.
theme
You can use the system setting to match their device or browser default, or you can specify a theme if you have such a setting in user profiles.
displayFiatCurrency
Link defaults to USD, or you can specify a fiat currency if you have such a setting in user profiles. See the Fiat currency support guide for more info on supported currencies
accessTokens
After users connect an exchange account, Mesh can maintain authorization so that the user doesn’t have to login again. This enables a 1 or 2 click transfer experience for return users. See the Use Mesh’s callback functions guide for more information on consuming Mesh SDK events and handling them with callback functions, and the Supercharge return-users guide to set up a return user experience
// Register the Link launcher as an Activity or Fragment property
private val linkLauncher = registerForActivityResult(LaunchLink()) { result ->
    when (result) {
        is LinkSuccess -> {
            // Called when Link returns payloads, such as a connected account or completed transfer.
            Log.i(LOG_TAG, "LinkSuccess: ${result.payloads}")
        }
        is LinkExit -> {
            // Called when Link exits without payloads, including user exits or errors.
            Log.i(LOG_TAG, "LinkExit: ${result.errorMessage}")
        }
    }
}

private fun launchMeshLink(linkToken: String, accessTokens: List<IntegrationAccessToken>? = null) {
    // Create LinkConfiguration
    val configuration = LinkConfiguration(
        token = linkToken,
        theme = LinkTheme.SYSTEM,
        language = "system",
        displayFiatCurrency = "USD",
        accessTokens = accessTokens,
    )

    // Launch
    linkLauncher.launch(configuration)
}
linkToken
Link token returned by the Mesh backend.
language
You can use the system setting to match their device or browser default, or you can specify a language if you have such a setting in user profiles. See the Multi-language support guide for more info on supported languages.
theme
You can use the system setting to match their device or browser default, or you can specify a theme if you have such a setting in user profiles.
displayFiatCurrency
Link defaults to USD, or you can specify a fiat currency if you have such a setting in user profiles. See the Fiat currency support guide for more info on supported currencies
accessTokens
After users connect an exchange account, Mesh can maintain authorization so that the user doesn’t have to login again. This enables a 1 or 2 click transfer experience for return users. See the Use Mesh’s callback functions guide for more information on consuming Mesh SDK events and handling them with callback functions, and the Supercharge return-users guide to set up a return user experience
return (
  <LinkConnect
    linkToken={linkToken}
    settings={{
      language: 'system',
      displayFiatCurrency: 'USD',
      accessTokens, // See "Supercharge return users" guide
    }}
    onIntegrationConnected={(payload: LinkPayload) => {
      // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
      console.log('[MESH LINK integration connected]', payload);
    }}
    onTransferFinished={(payload: TransferFinishedPayload) => {
      // Called after a transfer flow completes successfully or fails.
      console.log('[MESH LINK transfer finished]', payload);
    }}
    onEvent={(event: LinkEventType) => {
      // Allows you to handle other specific events
      console.log('[MESH LINK event]', event);
    }}
    onExit={(err?: string) => {
      // Called when Mesh Link exits, completes, is closed by the user, or fails during setup.
      console.log('[MESH LINK exited]');
    }}
  />
);
linkToken
Link token returned by the Mesh backend.
language
You can use the system setting to match their device or browser default, or you can specify a language if you have such a setting in user profiles. See the Multi-language support guide for more info on supported languages.
theme
You can use the system setting to match their device or browser default, or you can specify a theme if you have such a setting in user profiles.
displayFiatCurrency
Link defaults to USD, or you can specify a fiat currency if you have such a setting in user profiles. See the Fiat currency support guide for more info on supported currencies
accessTokens
After users connect an exchange account, Mesh can maintain authorization so that the user doesn’t have to login again. This enables a 1 or 2 click transfer experience for return users. See the Use Mesh’s callback functions guide for more information on consuming Mesh SDK events and handling them with callback functions, and the Supercharge return-users guide to set up a return user experience
Future<void> _showMeshLinkPage(
    String linkToken, {
    List<IntegrationAccessToken> accessTokens = const [],
}) async {
  // Show MeshSdk
  final result = await MeshSdk.show(
    context,
    configuration: MeshConfiguration(
      language: 'system', // See "Multi-language support" guide
      displayFiatCurrency: 'USD', // See "Fiat currency support" guide
      theme: ThemeMode.system,
      integrationAccessTokens: accessTokens, // See "Supercharge return users" guide
      linkToken: linkToken,
      onEvent: (event) {
        // Allows you to handle other specific events
        print('Mesh event: $event');
      },
      onError: (errorType) {
        // Callback for when Mesh Link exits due to an error
        print('Mesh exit: $errorType');
      },
      onSuccess: (payload) {
        // Callback for when the Mesh Link is successfully completed
        print('Mesh success: ${payload.page}');
      },
      onIntegrationConnected: (integration) {
        // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
        print('Integration connected: $integration');
      },
      onTransferFinished: (transfer) {
        // Called after a transfer flow completes successfully or fails.
        print('Transfer finished: $transfer');
      },
    ),
  );

  // Handle the result
  switch (result) {
    case MeshSuccess():
      print('Mesh link finished successfully');
    case MeshError():
      print('Mesh link error: ${result.type}');
  }

  // Alternatively, use `when` method
  result.when(
    success: (success) {
      final payload = success.payload;
      print('Mesh link success: ${payload.page}');
    },
    error: (error) {
      final errorType = error.type;
      print('Mesh link error: $errorType');
    },
  );
}
When generatePayLink: true in the The Link Token request, the response will include a paymentLink url. You can launch this Mesh-hosted webpage in a browser for your user, which avoids the need to download and install the Mesh SDK. When using this approach, it is recommended to also provide a url in the payLinkReturnUrl parameter which is where the user will be directed back to upon completion of their session. Payment Links are short-lived (10mins) and one-time use. Note: Paylinks are generally not recommended since they miss out on some session-specific SDK configurations, but they’re a handy fallback for teams with limited engineering resources or other technical constraints.
Image

What’s next

You’ve initialized the SDK — now you need to handle what comes back from it. Next up: Use Mesh’s callback functions — wire up the SDK’s callback functions to respond to key events like transfer completion and user exit.
AI coding reference — a compact summary of this page’s APIs, parameters, and patterns for use by AI coding assistants (following the llms.txt standard). Human readers can safely ignore this.llms.txt — Launch the Mesh SDKInitialize and launch the Mesh Link SDK. Three rendering modes for Web; native initialization for iOS, Android, React Native, Flutter.Web — createLink() params: renderType (‘embedded’ or ‘overlay’) | theme (‘system’/‘dark’/‘light’) | language (‘system’ or BCP 47) | displayFiatCurrency (ISO 4217, default ‘USD’) | accessTokens (MMT return-user array) | onIntegrationConnected | onTransferFinished | onExit | onEventWeb launch: connection.openLink(linkToken) (overlay) or connection.openLink(linkToken, 'custom-iframe-id') (embedded) | Close: connection.closeLink()Rendering options:
  • Embedded (recommended for web): iframe in your container. Min height 450px, recommended 665px.
  • Overlay: modal popup over your app.
  • Paylink: generatePayLink: true in Link Token request → paymentLink URL in response. No SDK install needed. Short-lived (10 min), single-use.
iOS (LinkConfiguration): linkToken | settings (LinkSettings: accessTokens, language, displayFiatCurrency, theme) | onIntegrationConnected | onTransferFinished | onEvent | onExitconfiguration.createHandler()handler.present(in: viewController)Android (LinkConfiguration): token | theme (LinkTheme.SYSTEM) | language | displayFiatCurrency | accessTokenslinkLauncher.launch(configuration). Results: LinkSuccess (has payloads) | LinkExit (has errorMessage)React Native: <LinkConnect linkToken={} settings={{language, displayFiatCurrency, accessTokens}} onIntegrationConnected onTransferFinished onEvent onExit />Flutter: MeshSdk.show(context, configuration: MeshConfiguration(linkToken, language, displayFiatCurrency, theme: ThemeMode.system, integrationAccessTokens, onEvent, onError, onSuccess, onIntegrationConnected, onTransferFinished))Web (overlay) — copy/paste snippet:
const connection = createLink({
  renderType: 'overlay', // Opens SDK on top of your web app
  theme: 'system',
  language: 'system',
  displayFiatCurrency: 'USD',
  accessTokens: accessTokens, // See "Supercharge return users" guide
  onIntegrationConnected: payload => {
    // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
    console.log('[MESH LINK integration connected]', payload)
  },
  onTransferFinished: payload => {
    // Called after a transfer flow completes successfully
    console.log('[MESH LINK transfer finished]', payload)
  },
  onExit: () => {
    // Called when Link is closed
    console.log('[MESH LINK exited]')
  },
  onEvent: ev => {
    // Allows you to handle other specific events
    console.log('[MESH LINK event]', ev)
  }
})

connection.openLink(linkToken)