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

# Integration Guide

This page guides you through integrating the Superlink SDK with your Android application.

## Prerequisites

Before you begin, ensure you have:

* **Completed the Superlink Partner Onboarding**: You must be a Superlink partner to use our SDK. If you aren't onboarded yet, please [reach out to us](https://superlink-staging.me/book-a-call).
* **Received a Partner ID**: You must have a Partner ID to initialize the marketplace modal. You will receive a Partner ID when you onboard as a partner.
* **An Android Project**: You must have an existing Android project to integrate the Android SDK.

## Add the SDK to your project

Add the following to your project's `settings.gradle` file:

```groovy theme={null}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        ...
        mavenCentral()
    }
}
```

or `build.gradle` file:

```groovy theme={null}
allprojects {
    repositories {
        ...
        mavenCentral()
    }
}
```

Then add the following to your app `build.gradle(.kts)` (or use the gradle version catalog `libs.versions.toml` file):

<CodeGroup>
  ```groovy theme={null}
  dependencies {
      ...
      def superlinkVersion = '1.1.1'
      implementation 'me.superlink:sdk:$superlinkVersion'
  }
  ```

  ```kotlin theme={null}
  dependencies {
      ...
      val superlinkVersion = "1.1.1"
      implementation("me.superlink:sdk:$superlinkVersion")
  }
  ```
</CodeGroup>

## Using the SDK

### `SuperlinkFragment`

Using the SDK requires connecting your app's user interface to the `SuperlinkFragment` [Fragment](https://developer.android.com/guide/fragments) subclass that is part of the Superlink SDK. To do this you must include the Superlink [NavGraph](https://developer.android.com/reference/androidx/navigation/NavGraph) into your application's NavGraph.

Here's what your NavGraph may look like:

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/app_flow"
    app:startDestination="@id/myAppStartFragment">

    <include
        android:id="@+id/superlink"
        app:graph="@navigation/superlink" />

    <fragment
        android:id="@+id/myAppStartFragment"
        android:name="me.superlink.exampleapp.MyAppStartFragment"
        android:label="fragment_myAppStart">

        <action
            android:id="@+id/action_myAppStartFragment_to_superlink"
            app:destination="@id/superlink" >
            <argument
                android:name="partnerId"
                app:argType="string" />
            <argument
                android:name="userInfo"
                app:argType="me.superlink.sdk.data.UserInfo" />
        </action>

    </fragment>
</navigation>
```

Then to initialize the SDK you have to navigate to the included Superlink NavGraph [destination](https://developer.android.com/reference/androidx/navigation/NavDestination) using a [navigation action](https://developer.android.com/guide/navigation/design/actions), passing through the required arguments:

* `partnerId`, a value of `argType` `string`, and
* `userInfo` value of `argType` `me.superlink.sdk.data.UserInfo` defined as:

```kotlin theme={null}
data class UserInfo(
    val wallets: List<Wallet>, 
    val externalUserId: String, 
    val email: String? = null, 
    val fullName:String? = null
) : Parcelable
```

and `Wallet` is defined as:

```kotlin theme={null}
data class Wallet(
    val address: String, 
    val coin: String
) : Parcelable
```

You may perform this navigation from your application's (Activity, Fragment or Jetpack Compose) user interface by invoking the navigation action defined in the NavGraph above with id `action_myAppStartFragment_to_superlink`, like so:

```kotlin theme={null}
...
val action = MyAppStartFragmentDirections.actionMyAppStartFragmentToSuperlink(
    partnerId = "<someStringRepresentingAPartnerId>",
    userInfo = UserInfo(
        listOf(
            Wallet(
                "<user-wallet-address>", // e.g. "0xbDA07FBc7b184Ac0561DdB67f355b1Bc5a9E4428"
                "<coin-type-of-wallet>" // e.g. "ETH"
            )
        ),
        externalUserId = "<user-identifier>" // e.g. "12345"
    )
)

findNavController().navigate(action)
```

The above navigation operation will display a web page inside of a web view component embedded in the Superlink Fragment just navigated to.

The rest of the Superlink SDK APIs are then available via the `SuperlinkViewModel` class which subclasses the Android framework [ViewModel](https://developer.android.com/reference/androidx/lifecycle/ViewModel) class and provides access to data and operations from the `Superlink` SDK.

### `SuperlinkViewModel`

In your Fragment above, you will need to instantiate the `SuperlinkViewModel` class as follows:

```kotlin theme={null}
val superlinkViewModel = activityViewModels<SuperlinkViewModel>()
```

You may also use any [other mechanisms for instantiating and scoping](https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-apis) the `SuperlinkViewModel` as required by your app's design.

Android Studio should auto-import the `SuperlinkViewModel` class and other Superlink classes, otherwise remember to manually import them:

```kotlin theme={null}
import me.superlink.sdk.SuperlinkFragment
import me.superlink.sdk.SuperlinkViewModel
import me.superlink.sdk.data.UserInfo
import me.superlink.sdk.data.Wallet
```

The following properties and methods of the `SuperlinkViewModel` comprise the rest of the APIs the SDK offers.

#### `transactionUrl: SharedFlow<String>`

Use the `SuperlinkViewModel` class to handle purchasing a domain. You do this by observing an instance's `transactionUrl` [SharedFlow](https://developer.android.com/kotlin/flow/stateflow-and-sharedflow#sharedflow) property, collecting the value it emits, performing your custom operation with it and then completing the transaction by calling the `completeTransaction` method on the instance.

The value will only be emitted when the user has selected crypto currency as their payment method. No value will be emitted for a fiat purchases.

The emitted value represents the transaction to be completed. It contains the recipient address, the coin type and the amount to be sent. The client application is expected to parse the URL and perform the transaction, before calling the `completeTransaction` method to notify the SDK that the transaction has been completed. Once completed, the the SDK will show a minting screen where the user waits for the transaction to be confirmed, before receiving their domain.

Here's an example of observing the property inside a `Fragment`:

```kotlin theme={null}
...
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    lifecycleScope.launch {
        // We use CREATED here because we want to be able to receive this data in the previous fragment but not leak 
        repeatOnLifecycle(Lifecycle.State.CREATED) {
            superlinkViewModel.transactionUrl.collect {
                Log.d("ExampleApp", "Transaction URL: $it")

                // This is just an example. This can be replaced with any custom UI, including using a different fragment since the view model is shared using the activity
                AlertDialog.Builder(requireContext())
                    .setTitle("Transaction URL").setMessage(it)
                    .setPositiveButton("OK") { _, _ -> 
                        // Do something with the collected value...

                        // ... And then notify the SDK you're done
                        superlinkViewModel.completeTransaction(transactionResult) 
                    }
                    .setNegativeButton("No") { _, _ -> }
                    .show()
            }
        }
    }

    ...
}
...
```

Here is an example of the value emitted by the `transactionUrl` property:

```
ethereum:0x965933D5C73ef443f3a2E4B370c3b6C964fc76eC?value=1.3062319352247146e17
```

Parsing the above yields:

* **coin type**: `ethereum`
* **amount**: `1.3062319352247146e17`
* **recipient**: `0x965933D5C73ef443f3a2E4B370c3b6C964fc76eC`

#### `completeTransaction(transactionID: String)`

Like mentioned in the [`transactionUrl: SharedFlow<String>` section above](#transactionurl-sharedflowstring) the `completeTransaction()` method allows your app to handover the transaction identifier back to the Superlink SDK. This will notify the SDK that the transaction has been completed and that the user can proceed to the minting screen.

#### `transactionID: SharedFlow<String>`

#### `messageToSign: SharedFlow<String>`

The Superlink SDK uses this property to provide a transaction that requires performing a digital signing operation by your application. Quite like the [`transactionUrl: SharedFlow<String>`](#transactionurl-sharedflowstring) property, you observe this property and grab the emitted value for digital signing in your own application process.

The message will be emitted when the user claims a free username. The client application will be required to prompt the user to sign the message. Once the user signs the message, and the `completeMessageSigning` function is executed, the signed wessage will be sent back to the SDK which in turn sends it to the Superlink backend for verification. When the signed message is validated the user is given a free username.

Here's an example:

```kotlin theme={null}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.CREATED) {
            superLinkViewModel.messageToSign.collect {
                Log.d("ExampleApp", "messageToSign: $it")

                // Grab the messageToSign and trigger a process to sign it...
                AlertDialog.Builder(requireContext()).setTitle("Sign This Message?")
                    .setMessage(it)
                    .setPositiveButton("Yes") { _, _ ->
                        // Initiate message signing ....
                        val messageSigned = it

                        // Now, pass through the signed message to the SDK
                        superLinkViewModel.completeMessageSigning(it, messageSigned)
                    }
                    .setNegativeButton("No") { _, _ -> }
                    .show()
            }
        }
    }
    ...
}
```

#### `completeMessageSigning(originalMessage: String, signedMessage: String)`

Already mentioned in [`messageToSign: SharedFlow<String>` above](#messagetosign-sharedflowstring), the `completeMessageSigning(...)` passes through to the SDK:

* `originalMessage`: to identify the transaction that has been signed;
* `signedMessage`: the digital signature

#### `closeReason: SharedFlow<String>`

The SDK closes the web view displaying the Superlink web content when a transaction is [complete](#completemessagesigningoriginalmessage-string-signedmessage-string) or when a transaction is [signed](#completemessagesigningoriginalmessage-string-signedmessage-string). The `closeReason` property simply provides a `success` or empty string value to inform your application that the SDK has shutdown the web view. Like the other properties already mentioned, you'd have to observe it and handle changes to it accordingly, most likely to navigate back from the [SuperlinkFragment](#superlinkfragment) and back to your app's previous view.

Here's how you can do this:

```kotlin theme={null}
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...
    lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.CREATED) {
                superLinkViewModel.closeReason.collect {
                    Log.d("ExampleApp", "closeReason: $it")

                    if (it == "success") {
                        findNavController().navigateUp()

                        val action = PurchaseFragmentDirections.actionGlobalPurchaseFragment()
                        findNavController().navigate(action)
                    } else {
                        findNavController().navigateUp()
                    }
                }
            }
        }
    ...
}
```

### Custom view while SDK is loading

By including a `layout/superlink_loading_view.xml` file in your project's [layout resource directory](https://developer.android.com/guide/topics/resources/layout-resource), you can customize the loading screen that the Superlink SDK displays when loading the web content in the web view. Otherwise, Superlink uses a default view.

Here's an example:

```xml theme={null}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:text="Getting your transaction ready"
        app:layout_constraintBottom_toTopOf="@+id/progress"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <com.google.android.material.progressindicator.CircularProgressIndicator
        android:id="@+id/progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```
