๐Ÿ“ฑ Android

Overview

Sharpsports Android is a library built in Kotlin.

It is intended to be used as the integration path for your native Android app.

๐Ÿšง

Be sure to enable the Native SDK toggle under Settings->Account in the SharpSports dashboard to enable SDK Required books in the Linking UI.

Access

Request access by emailing [email protected].

Please generate a Personal Access Token (PAT) to use when installing the library into your project. This should be a classic token with permission scope read:packages.
For details on how to create a classic PAT see: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token

Importing the Library

To add the package to your app, make sure that you add the sharpsports-android and LiquidCore repositories to your repositories block in either your settings.gradle or build.gradle file. Create a github.properties file in the root-level of your project with your GitHub username and personal access token. You can also add these properties to your system environment variables instead.

ext.usr='your github username'
ext.key='your personal access token'

Then, in either your settings.gradle or build.gradle file:

def githubProperties = new Properties()
githubProperties.load(new FileInputStream(file("github.properties")))

repositories {
   maven {
       name = 'GitHubPackages'
       url = 'https://maven.pkg.github.com/LiquidPlayer/LiquidCore'
       credentials {
          username = githubProperties['ext.usr'] ?: System.getenv("GITHUB_USER_NAME")
          password = githubProperties['ext.key'] ?: System.getenv("GITHUB_TOKEN")
       }
   }
   maven {
       name = "GitHubPackages"
       url = uri("https://maven.pkg.github.com/sharpsports/sharpsports-android")
       credentials {
           username = githubProperties['ext.usr'] ?: System.getenv("GITHUB_USER_NAME")
           password = githubProperties['ext.key'] ?: System.getenv("GITHUB_TOKEN")
       }
   }
}

And finally, add the implementation block in the app you want to consume the library using:

implementation 'com.sharpsports.mobile:android:1.0.3'

Getting Started

To see an example integration view the files located at app/src/main/java/com/example/simplebuttontestapp/

Generate a Mobile Authentication Token

First, you should create an API endpoint in your backend to retrieve a mobileAuthToken from the SharpSports v1/mobile/auth endpoint. Your API endpoint should:

  1. Require that the bettor is authenticated in your application
  2. Pass the internalId of the authenticated bettor as data to the v1/mobile/auth endpoint
  3. Return the value of {token: <mobileAuthToken>} that you receive from the v1/mobile/auth endpoint

The usage of the v1/mobile/auth endpoint is as follows:

curl -H "Authorization: Token <your_private_api_key>" -d "internalId=<bettor_internal_id> https://api.sharpsports.io/v1/mobile/auth

This returns {token: <mobileAuthToken>} that is needed to intialize the SharpSportsMobile object.

Note: The example app provided in this repository is instructive as it shows the call to /v1/mobile/auth, but this call should be made from your own server so your private API key is not present in the client

Initialize SharpSportsMobile

Create your SharpSportsMobile singleton instance as follows:

val mobileAuthToken = mobileAuthService.getMobileAuthToken()

val config = {
  publicKey = <your_public_key>
  internalId = <bettor_internal_id>
  mobileAuthToken = mobileAuthToken
}

sharpSportsMobile = SharpSportsMobile.getInstance(config)

Next, call the context method to retrieve a cid to load into your WebView instance.

coroutineScope.launch(Dispatchers.IO) {
    val cid = sharpSportsMobile?.getContext()
    val url = // build the url you want to host
}

You can optionally set the styling on the UI by passing a parameter to the getContext method. This parameter can have the values dark, light or system (uses whatever is the default for the user's browser).

val cid = sharpSportsMobile?.getContext("dark")

Next, in your WebView, call the addJavascriptInterface method on the SharpSportsMobile object, and make sure JavaScript is enabled:

@SuppressLint("SetJavaScriptEnabled")
@Composable
fun WebViewScreen(
    cid: String,
    viewModel: SharpSportsViewModel,
    onCloseWebView: () -> Unit = {}
) {
    val url = "https://ui.sharpsports.io/link/$cid"
    AndroidView(factory = {
        WebView.setWebContentsDebuggingEnabled(true)
        WebView(it).apply {
            viewModel.sharpSportsMobile?.addJavaScriptInterface(this)
            layoutParams = ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
            webViewClient = ExampleWebViewClient(viewModel.sharpSportsMobile, onCloseWebView)
            settings.javaScriptEnabled = true
            loadUrl(url)
        }
    }, update = {
        it.loadUrl(url)
    })
}

In your WebViewClient, override doUpdateVisitedHistory as follows, and optionally set the delegate:

class ExampleWebViewClient(
    private val sharpSportsMobile: SharpSportsMobile?,
    private val onCloseWebView: () -> Unit
): WebViewClient(), SharpSportsMobileDelegate {

    init {
        this.also { sharpSportsMobile?.delegate = WeakReference(it) }
    }

    override fun doUpdateVisitedHistory(view: WebView?, url: String?, isReload: Boolean) {
        sharpSportsMobile?.doUpdateVisitedHistory(view, url, isReload)
        super.doUpdateVisitedHistory(view, url, isReload)
    }

    override fun dismissWebView() {
        onCloseWebView()
    }
}

You can reference the example integration under the app directory.

Refreshing

The Refresh method will allow you to make refresh requests to the SharpSports API.

Arguments

The Refresh method will allows you to refresh on all accounts associated with the internalId that you provided when initializing the SharpSportsMobile object. You can also pass a bettorId to refresh all accounts associated with that bettorId or a bettorAccountId to refresh just a specific accountId.

You can optionally pass reverify: true as an argument to attach the reverify query parameter to the refresh request.

bettorId: String?
bettorAccountId: String?
reverify: Bool

Usage

Refresh by InternalID

sharpSportsMobile.refresh(RefreshOption.InternalId(internalId), reverify)

corresponds to the API call

POST https://api.sharpsports.io/v1/bettors/<internalID>/refresh

Refresh by BettorID

sharpSportsMobile.refresh(RefreshOption.BettorId(bettorId), reverify)

corresponds to the API call

POST https://api.sharpsports.io/v1/bettors/<BTTR_ID>/refresh

Refresh by BettorAccountID

sharpSportsMobile.refresh(RefreshOption.BettorAccountId(bettorAccountId), reverify)

corresponds to the API call

POST https://api.sharpsports.io/v1/bettorAccounts/<BACT_ID>/refresh

Reverify

sharpSportsMobile.refresh(.bettorAccountId("BACT_ID"), reverify: true)

corresponds to the API call

POST https://api.sharpsports.io/v1/bettorAccounts/<BACT_ID>/refresh?reverify=true