Overview
The react native sdk is a customizable package built in typescript that provides authenticated access to the SharpSports Context
and Refresh
methods. It is intended to be used as the integration path for React-Native mobile applications.
Be sure to enable the
Native SDK
toggle under Settings->Account in the SharpSports dashboard to enableSDK Required
books in the Linking UI.
Getting Started
Access
Request access by emailing [email protected].
Installation
Once your github account has been added as an outside collaborator to this sharpsports-mobile package please generate a Personal Access Token (PAT) to use when installing the package 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
- Authenticate to the github NPM registry in one of two ways
i) Add //npm.pkg.github.com/:_authToken=TOKEN
(with your PAT) to an ~/.npmrc
file.
ii) Use npm login
$ npm login --scope=@sharpsports --registry=https://npm.pkg.github.com
> Username: USERNAME
> Password: TOKEN
> Email: PUBLIC-EMAIL-ADDRESS
- Create a new file
.npmrc
in the same directory as yourpackage.json
with the following
@sharpsports:registry=https://npm.pkg.github.com
This file must be pushed to github with your project.
- Add
"@sharpsports/sharpsports-mobile": VERSION
to yourpackage.json
- Run npm install
See https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry for more details
- Install additional React-Native dependencies directly in your application - these cannot be installed as sub-depedencies to the sharpsports-mobile package as it causes issues in the iOS buid. To see the compatible versions of these dependencies view the
devDependencies
inpackage.json
of the sharpsports-mobile package.
npm install @react-native-community/netinfo
npm install @react-native-cookies/cookies
npm install @pusher/pusher-websocket-react-native
- Notes for Expo Users:
- Please ensure you are using Expo version >46.0
- Once sharpsports-mobile and necessary react-native dependencies are installed in your app, you will not be able to run your application locally using the expo managed workflow. Instead use the
eas-cli
or the following method on iOS:- iOS:
npx expo prebuild && cd ios && pod install
and then open the resulting workspace in XCode
- iOS:
Note: iOS deployment target must be >=13.0
Generate a Mobile Authentication Token
In order to initialize the SharpSports
object in your application you need to generate a mobileAuthToken
in your backend and retrieve it client-side.
First create an API endpoint in your backend to retrieve the mobileAuthToken
from the SharpSports /v1/mobile/auth
endpoint. Your API endpoint should:
- Require that the bettor is authenticated in your application
- Pass the
internalId
of the authenticated bettor as data to the/v1/mobile/auth
endpoint - Return the value of
{"token":<mobileAuthToken>}
you recieve from the/v1/mobile/auth
endpoint
Example usage of /v1/mobile/auth
is shown below in node:
const privateKey = 'my-private-api-key'
const internalId = 'internal-id-of-authenticated-bettor'
const HEADERS = {
"Authorization" : `Token ${privateKey}`,
"Content-Type": "application/json"
}
const DATA = {
"internalId": internalId
}
const OPTS = {
method: 'POST',
headers: HEADERS,
body: JSON.stringify(DATA)
};
let response = await fetch('https://api.sharpsports.io/v1/mobile/auth',OPTS)
let data = await response.json() //data takes the form {"token": <mobileAuthToken>}
Your application should fetch the mobileAuthToken
once a bettor has logged in to your app and you can use it to initialize the SharpSports
object.
The example-app
in this repository is instructive, but shows the call that is to be made server-side within the app itself.
Initialize the SharpSports Object
Import the SharpSports package into your app and initialize.
import SharpSports from '@sharpsports/sharpsports-mobile';
const internalId = 'internal-id-of-authenticated-bettor';
const publicKey = 'my-public-api-key';
const mobileAuthToken = 'mobile-auth-token';
const sharpsports = new SharpSports(internalId,publicKey,mobileAuthToken);
Create a Linking Session in a WebView
The sharpsports.Context
method corresponds to the API call POST https://api.sharpsports.io/v1/context
. It returns a Promise that when resolved contains a context ID - {"cid": <cid>}
.
Use this cid
to render a webview that navigates to https://ui.sharpsports.io/link/<cid>
(or a specific book/region if you prefer - see https://docs.sharpsports.io/#create-your-own-button-for-each-book). Make sure to generate a new cid
each time the webview is opened; don't create a cid
on app load and use for multiple sessions.
The WebView that you create should do the following:
- Use a state variable as the source uri. This state variable should be initialized using the response from the
Context
method and should be updated inonNavigationStateChange
- Inject JS returned by
sharpsports.getInjectedJavascript()
on every new page load - Call
sharpsports.onNavigationStateChange
as part of the WebViewonNavigationStateChange
handler - Call
sharpsports.onMessage
as part of the WebviewonMessage
handler - Have third partry cookies enabled
- When the process of linking an account is complete, the Sharpsports UI will naviage to
https://ui.sharpsports.io/done
. You can hook on to this URL to exit the webview.
This can be achieved by following this example:
import React,{ useState } from 'react';
import SharpSports from '@sharpsports/sharpsports-mobile'
const internalId = 'your-internal-id'
const SSpublicKey = 'your-SharpSports-public-key'
const mobileAuthToken = 'mobile-auth-token'
const sharpsports = new SharpSports(internalId,SSpublicKey,mobileAuthToken)
const [webviewUrl, setWebviewUrl] = useState(null)
const [cid, setCid] = useState(null)
...
onClick = async() => {
const response = await sharpsports.Context()
const data = await response.json()
setCid(data.cid)
setWebviewUrl(`https://ui.sharpsports.io/link/${data.cid}`)
}
_onMessage = (data) => {
//Any other onMessage handling that you have in your app
sharpsports.onMessage(data,cid)
}
_onNavigationStateChange = (data) => {
setWebviewUrl(data.url) //This is required to make sure JS is injected on every new page
//Any other navigation handling that you have in your app
//Case for exiting webview on /done url
sharpsports.onNavigationStateChange(data)
}
...
<WebView
source={{ uri: webviewUrl }} //this is required to block webview from linking out to external apps
injectedJavaScript={sharpsports.getInjectedJavascript()}
onNavigationStateChange={_onNavigationStateChange}
onMessage={_onMessage}
thirdPartyCookiesEnabled={true}
/>
Context Method
The sharpsports.Context()
method allows you to generate a session for SharpSports UI components
Arguments
All of the arguments for the Context
method are optional.
Setting Light/Dark Mode
You can set the SharpSports UI background color by using the uiMode
parameter
dark
: dark mode background
light
: light mode background
system
: use device's default setting
sharpsports.Context({uiMode: <light|dark|system>})
Generate a Context for Best Price Widget
If you need to generate a context for the SharpSports Best Price Widget you use the bestPrice
parameter. Then navigate to the url https://ui.sharpsports.io/best-price/<cid>
.
sharpsports.Context({bestPrice: true})
Refreshing Accounts
The sharpsports.Refresh()
method allows you to make refresh requests to the SharpSports API.
Version 3.2.0 contains a required alert message that appears when the Refresh method is called for particular books.
Arguments
By default the Refresh
method will run a refresh on all accounts associated with the internalId
that you provided when initializing the SharpSports
object. Optionally you can pass a bettorId
to refresh all accounts associated with that ID or a bettorAccountId
to refresh just a specific account.
You can also optionally pass reverify: true
as an argument to attach the reverify query parameter to the refresh request.
bettorId?: string;
bettorAccountId?: string;
reverify?: boolean;
Usage
Refresh by InternalID
sharpsports.Refresh()
corresponds to the API call
POST https://api.sharpsports.io/v1/bettors/<internalID>/refresh
Refresh by BettorID
sharpsports.Refresh({bettorId: <BTTR_ID>})
corresponds to the API call
POST https://api.sharpsports.io/v1/bettors/<BTTR_ID>/refresh
Refresh by BettorAccountID
sharpsports.Refresh({bettorAccountId: <BACT_ID>})
corresponds to the API call
POST https://api.sharpsports.io/v1/bettorAccounts/<BACT_ID>/refresh
Reverify
sharpsports.Refresh({bettorAccountId: <BACT_ID>, reverify: true})
corresponds to the API call
POST https://api.sharpsports.io/v1/bettorAccounts/<BACT_ID>/refresh?reverify=true