Requirements

Installation

Add io.elements.pay:treasure to your build.gradle dependencies.

Gradle

dependencies {
    implementation 'io.elements.pay:treasure:1.0.0-beta01'
}

TreasureHost

TreasureHost class is the main interface that communicates between client application and flexible UI SDK. You can initialize TreasureHost in the following way.

val treasureHost = TreasureHost( configuration = Treasure.Configuration( TreasureEnvironment.sandbox("Your client token goes here...") ) )

Set up client side dependencies

Treasure provides interfaces to support passing client dependencies to itself.

Load Images

Treasure allows you to pass customized image downloader to the SDK and Treasure will use it to load images when needed.

See code below for an example on how to create a customized image loader using popular image loading libraries -> Coil

class ImageLoader : TreasureImageLoadable { @OptIn(ExperimentalCoilApi::class) @Composable override fun getPainter(url: String): Painter { return rememberImagePainter(data = url) } }

Now you can pass the customized image loader to TreasureDependency in the following way.

TreasureDependency.getInstance().imageLoader = ImageLoader()

Theme + UI resources

Treasure supports dark/light themes at the moment. Client side colors/fonts/image are passed to TreasureDependency using ThemeComponent interface.

Fonts

Treasure supports providing fonts using the following way

enum class FontPlate(val decodeName: String) { PRIMARY(decodeName = "primary") { override fun toDarkThemeFont() = FontAndSize(io.blocks.treasure.R.font.poppins_medium, 20) override fun toLightThemeFont() = FontAndSize(io.blocks.treasure.R.font.poppins_medium, 20) }, SECONDARY(decodeName = "secondary") { override fun toLightThemeFont() = FontAndSize(io.blocks.treasure.R.font.poppins_medium, 17) override fun toDarkThemeFont() = FontAndSize(io.blocks.treasure.R.font.poppins_medium, 17) }; abstract fun toLightThemeFont(): FontAndSize abstract fun toDarkThemeFont(): FontAndSize companion object { fun toFonts(): ThemeComponent<FontAndSize> { val result: MutableMap<String, MutableMap<SystemThemeType, FontAndSize>> = mutableMapOf() for (type in FontPlate.values()) { result[type.decodeName] = mutableMapOf( Pair(SystemThemeType.DARK, type.toDarkThemeFont()), Pair(SystemThemeType.LIGHT, type.toLightThemeFont()) ) } return ThemeComponent(values = result) } } }

function toFonts() shows how to provide a ThemeComponent object to the theme class and then passing to TreasureDepedency

So once Treasure SDK sees "primary" in fonts json block, it will be mapped to the primary font provided by the application.

Colors

Similar to fonts, Treasure currently supports two different ways of initializing colors.

  1. Using hex string
"text_color": "#000000" // this represents a black text color
  1. Using color string representation provided by the application.
"text_color": "primary"
enum class ColorPlate(val decodeName: String) { PRIMARY(decodeName = "primary") { override fun toDarkThemeColor() = Color.White override fun toLightThemeColor() = Color.Black }, SECONDARY(decodeName = "secondary") { override fun toLightThemeColor() = Color.DarkGray override fun toDarkThemeColor() = Color.White }; abstract fun toLightThemeColor(): Color abstract fun toDarkThemeColor(): Color companion object { fun toColors(): ThemeComponent<Color> { val result: MutableMap<String, MutableMap<SystemThemeType, Color>> = mutableMapOf() for (type in ColorPlate.values()) { result[type.decodeName] = mutableMapOf( Pair(SystemThemeType.DARK, type.toDarkThemeColor()), Pair(SystemThemeType.LIGHT, type.toLightThemeColor()) ) } return ThemeComponent(values = result) } } }

Images

Treasure provides initializing images from local assets folder and remote download URL. In order to use images from local assets folder you can do the following.

import io.blocks.treasure.R import io.blocks.treasure.core.view.theme.SystemThemeType import io.blocks.treasure.core.view.theme.ThemeComponent enum class LocalImages(val decodeName: String) { MASTERCARD(decodeName = "mastercard") { override fun toDarkThemeImage() = R.drawable.ic_mastercard_32 override fun toLightThemeImage() = R.drawable.ic_mastercard_32 }, SETTINGS(decodeName = "settings") { override fun toLightThemeImage() = io.blocks.treasure.R.drawable.ic_settings override fun toDarkThemeImage() = io.blocks.treasure.R.drawable.ic_settings }; abstract fun toLightThemeImage(): Int abstract fun toDarkThemeImage(): Int companion object { fun toImages(): ThemeComponent<Int> { val result: MutableMap<String, MutableMap<SystemThemeType, Int>> = mutableMapOf() for (type in values()) { result[type.decodeName] = mutableMapOf( Pair(SystemThemeType.DARK, type.toDarkThemeImage()), Pair(SystemThemeType.LIGHT, type.toLightThemeImage()) ) } return ThemeComponent(values = result) } } }

Constructing theme object from fonts, colors, images and styles.

In order for treasure to utilize provided resources, you need to construct an object that implements ThemeRegistrable interface and then pass that object to TreasureDependency.

data class Theme( override var styles: Map<String, ElementStyle>?, override var fonts: ThemeComponent<FontAndSize>?, override var colors: ThemeComponent<Color>?, override var images: ThemeComponent<Int>? ): ThemeRegistrable { // Providing typefaces that can be interpreted in the server json override fun getTypeface(id: String): Int? { return when (id) { "Poppins-Medium" -> R.font.poppins_medium "Avenir-Medium" -> R.font.poppins_medium else -> null } } // Providing interfaces that TreasureSDK can read and generate the image that mapped to the naming. override fun getLocalImage(id: String): Int? { return when (id) { "checkmark_grey" -> io.blocks.treasure.R.drawable.ic_grey_check "payment_mastercard" -> io.blocks.treasure.R.drawable.ic_mastercard_32 "ic_rider_payment_paypal" -> io.blocks.treasure.R.drawable.ic_paypal_32 "ic_google_pay" -> io.blocks.treasure.R.drawable.ic_googlepay_32 "disclosure_indicator_dark" -> R.drawable.ic_glyph_chevron "delete_card_gray" -> io.blocks.treasure.R.drawable.ic_circle_x "dark_gray_close" -> io.blocks.treasure.R.drawable.ic_close_gray "ic_supreme_payment_creditcard" -> io.blocks.treasure.R.drawable.ic_card_blank "lime_logomark" -> io.blocks.treasure.R.drawable.ic_lime_cash "supreme_close_light_background" -> io.blocks.treasure.R.drawable.ic_close_round else -> null } } } TreasureDependency.getInstance().theme = Theme( styles = null, fonts = FontPlate.toFonts(), colors = ColorPlate.toColors(), images = LocalImages.toImages() )

Starting Treasure UI

Method 1: Load from Elements' server.

private fun loadFromCheckoutUI() { treasureHost.loadFragmentFromCheckoutUI { replaceFragment(it) } }

Method 2: Load from local file

private fun loadFromLocal() { val fileContent = resources.openRawResource(R.raw.payment_methods_view) .bufferedReader().use { it.readText() } val fragment = treasureHost.loadFragmentFromLocal(fileContent) replaceFragment(fragment) }

Example App

Clone this repo and open/build the project. The demo app demonstrated how to use Treasure.