Skip to content

Commit

Permalink
merge(#25): off-ramp
Browse files Browse the repository at this point in the history
  • Loading branch information
pawel-zak authored Nov 15, 2022
1 parent a1dedb4 commit c10f9e4
Show file tree
Hide file tree
Showing 11 changed files with 246 additions and 14 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.38'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
26 changes: 24 additions & 2 deletions demo/src/main/java/ramp/network/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ package ramp.network.demo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import network.ramp.sdk.events.model.Asset
import network.ramp.sdk.events.model.OfframpSale
import network.ramp.sdk.events.model.Purchase
import network.ramp.sdk.facade.Config
import network.ramp.sdk.facade.Flow
import network.ramp.sdk.facade.RampCallback
import network.ramp.sdk.facade.RampSDK
import ramp.network.demo.databinding.ActivityMainBinding
Expand Down Expand Up @@ -32,7 +35,8 @@ class MainActivity : AppCompatActivity() {
hostLogoUrl = "https://ramp.network/assets/images/Logo.svg",
hostAppName = "My App",
url = "https://ri-widget-dev2.firebaseapp.com",
hostApiKey = "input your host api key"
hostApiKey = "3qncr4yvxfpro6endeaeu6npkh8qc23e9uadtazq",
enabledFlows = setOf(Flow.OFFRAMP, Flow.ONRAMP)
)
// 4. Implement callbacks
val callback = object : RampCallback {
Expand All @@ -51,10 +55,28 @@ class MainActivity : AppCompatActivity() {
override fun onWidgetClose() {
Log.d("MainActivity", "onWidgetClose")
}

override fun offrampSendCrypto(
assetInfo: Asset,
amount: String,
address: String
) {
Log.d(
"MainActivity",
"offrampSendCrypto assetInfo: $assetInfo amount: $amount address: $address"
)
}

override fun onOfframpSaleCreated(
sale: OfframpSale,
saleViewToken: String,
apiUrl: String
) {
Log.d("MainActivity", "onOfframpSaleCreated ${sale.id} ${sale.createdAt} crypto: ${sale.crypto.amount} ${sale.crypto.assetInfo}")
}
}
// 5. Start widget
rampSdk.startTransaction(this, config, callback)

}
}
}
8 changes: 4 additions & 4 deletions rampsdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 32
versionCode 14
versionName "1.3.11"
versionCode 15
versionName "2.0.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
buildConfigField 'String', 'VERSION', "\"${defaultConfig.versionName}\""
}

buildTypes {
Expand Down Expand Up @@ -60,7 +61,6 @@ dependencies {
implementation 'com.squareup.moshi:moshi-kotlin:1.14.0'

kapt("com.squareup.moshi:moshi-kotlin-codegen:1.14.0")

implementation 'com.passbase:passbase_sdk:2.13.6'

def dagger_version = "2.40.4"
Expand All @@ -86,7 +86,7 @@ afterEvaluate {
from components.release
groupId = 'com.github.RampNetwork'
artifactId = 'ramp-sdk-android'
version = '1.3.11'
version = '2.0.0'
}
}
}
Expand Down
34 changes: 31 additions & 3 deletions rampsdk/src/main/java/network/ramp/sdk/events/model/Events.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ package network.ramp.sdk.events.model

import com.squareup.moshi.JsonClass

sealed class Event(val type: EventType)
sealed class Event(val type: EventType) {
companion object {
const val SEND_CRYPTO_EVENT_VERSION = 1
const val SEND_CRYPTO_RESULT_EVENT_VERSION = 1
}
}

@JsonClass(generateAdapter = true)
data class WidgetClose(var payload: WidgetClosePayload? = null) : Event(EventType.WIDGET_CLOSE)
Expand All @@ -20,7 +25,10 @@ internal data class OpenLink(var payload: OpenLinkPayload) : Event(EventType.OPE
internal data class WidgetConfigDone(var payload: String?) : Event(EventType.WIDGET_CONFIG_DONE)

@JsonClass(generateAdapter = true)
internal data class BackButtonPressed(var payload: String?): Event(EventType.BACK_BUTTON_PRESSED)
internal data class WidgetConfigFailed(var payload: String?) : Event(EventType.WIDGET_CONFIG_FAILED)

@JsonClass(generateAdapter = true)
internal data class BackButtonPressed(var payload: String?) : Event(EventType.BACK_BUTTON_PRESSED)

@JsonClass(generateAdapter = true)
internal data class KycInit(var payload: KycInitPayload) : Event(EventType.KYC_INIT)
Expand All @@ -40,19 +48,39 @@ internal data class KycSubmitted(var payload: KycSubmittedPayload) : Event(Event
@JsonClass(generateAdapter = true)
internal data class KycError(var payload: KycErrorPayload) : Event(EventType.KYC_ERROR)

@JsonClass(generateAdapter = true)
internal data class SendCrypto(
var payload: SendCryptoPayload,
var eventVersion: Int = SEND_CRYPTO_EVENT_VERSION
) : Event(EventType.SEND_CRYPTO)

@JsonClass(generateAdapter = true)
internal data class SendCryptoResult(
var payload: SendCryptoResultPayload,
var eventVersion: Int = SEND_CRYPTO_RESULT_EVENT_VERSION
) : Event(EventType.SEND_CRYPTO_RESULT)

@JsonClass(generateAdapter = true)
internal data class OfframpSaleCreated(var payload: OfframpSaleCreatedPayload) :
Event(EventType.OFFRAMP_SALE_CREATED)

@JsonClass(generateAdapter = false)
enum class EventType {
WIDGET_CLOSE,
OPEN_LINK,
KYC_INIT,
WIDGET_CONFIG_DONE,
WIDGET_CONFIG_FAILED,
BACK_BUTTON_PRESSED,
PURCHASE_FAILED,
PURCHASE_CREATED,
KYC_STARTED,
KYC_FINISHED,
KYC_ABORTED,
KYC_SUBMITTED,
KYC_ERROR
KYC_ERROR,
SEND_CRYPTO,
SEND_CRYPTO_RESULT,
OFFRAMP_SALE_CREATED
}

48 changes: 46 additions & 2 deletions rampsdk/src/main/java/network/ramp/sdk/events/model/Payloads.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package network.ramp.sdk.events.model

import android.os.Parcelable
import com.squareup.moshi.JsonClass
import kotlinx.parcelize.Parcelize

@JsonClass(generateAdapter = true)
internal data class OpenLinkPayload(val linkType: String, val url: String)
Expand Down Expand Up @@ -45,6 +47,18 @@ internal data class KycSubmittedPayload(
@JsonClass(generateAdapter = true)
internal data class KycErrorPayload(var verificationId: Int = 0)

@JsonClass(generateAdapter = true)
internal data class SendCryptoPayload(
var assetInfo: Asset,
var amount: String = "",
var address: String = ""
)

@JsonClass(generateAdapter = true)
internal data class SendCryptoResultPayload(
var txHash: String? = null,
var error: String? = null
)

@JsonClass(generateAdapter = true)
data class PurchaseCreatedPayload(
Expand All @@ -53,6 +67,14 @@ data class PurchaseCreatedPayload(
val apiUrl: String
)

@JsonClass(generateAdapter = true)
data class OfframpSaleCreatedPayload(
val sale: OfframpSale,
val saleViewToken: String,
val apiUrl: String
)


@JsonClass(generateAdapter = true)
data class Purchase(
val id: String,
Expand Down Expand Up @@ -82,10 +104,32 @@ data class Purchase(
)

@JsonClass(generateAdapter = true)
data class OfframpSale(
val id: String,
val createdAt: String, // ISO date-time string
val crypto: Crypto,
val fiat: Fiat
)

@JsonClass(generateAdapter = true)
data class Crypto(
val amount: String,
val assetInfo: Asset, // description of the purchased asset (address, symbol, name, decimals, chain)
)

@JsonClass(generateAdapter = true)
data class Fiat(
val amount: Double,
val currencySymbol: String, // description of the purchased asset (address, symbol, name, decimals, chain)
)

@JsonClass(generateAdapter = true)
@Parcelize
data class Asset(
val address: String? = null, // 0x-prefixed address for ERC-20 tokens, `null` for ETH
val symbol: String, // asset symbol, for example `ETH`, `DAI`, `USDC`
val name: String,
val decimals: Long, // token decimals, e.g. 18 for ETH/DAI, 6 for USDC
val type: String // asset type & network, e.g. `ETH`, `ERC20`, `MATIC_ERC20`
)
val type: String, // asset type & network, e.g. `ETH`, `ERC20`, `MATIC_ERC20`
val chain: String // asset chain, for example `ETH`, `BSC`, `POLKADOT`
) : Parcelable
24 changes: 22 additions & 2 deletions rampsdk/src/main/java/network/ramp/sdk/facade/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ data class Config(
*/
var swapAsset: String = "",

/***
* An optional string parameter, works exactly the same as swapAsset but applies only for off-ramp.
*/
var offrampAsset: String = "",

/**
* An optional int parameter that pre-sets the amount of crypto your user will buy.
* If left blank, the user will choose the amount on their own.
Expand Down Expand Up @@ -94,6 +99,21 @@ data class Config(
* An optional string parameter that allows our system to properly recognize and count purchases made through your API integration.
* Example: "the API key you received"
*/
var hostApiKey: String = ""
var hostApiKey: String = "",

var defaultFlow: Flow = Flow.ONRAMP,

var enabledFlows: Set<Flow> = setOf(Flow.ONRAMP),

var offrampWebhookV3Url: String = "",

var useSendCryptoCallback: Boolean? = null,

var useSendCryptoCallbackVersion: Int? = SEND_CRYPTO_CALLBACK_VERSION

) : Parcelable{

) : Parcelable
companion object{
const val SEND_CRYPTO_CALLBACK_VERSION = 1
}
}
9 changes: 9 additions & 0 deletions rampsdk/src/main/java/network/ramp/sdk/facade/Flow.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package network.ramp.sdk.facade

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
enum class Flow : Parcelable {
OFFRAMP, ONRAMP
}
14 changes: 14 additions & 0 deletions rampsdk/src/main/java/network/ramp/sdk/facade/RampCallback.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
package network.ramp.sdk.facade

import network.ramp.sdk.events.model.OfframpSale
import network.ramp.sdk.events.model.Purchase
import network.ramp.sdk.events.model.Asset

interface RampCallback {

fun onPurchaseFailed()

fun onPurchaseCreated(purchase: Purchase, purchaseViewToken: String, apiUrl: String)

fun onOfframpSaleCreated(
sale: OfframpSale,
saleViewToken: String,
apiUrl: String
)

fun onWidgetClose()

fun offrampSendCrypto(
assetInfo: Asset,
amount: String,
address: String
)
}
35 changes: 34 additions & 1 deletion rampsdk/src/main/java/network/ramp/sdk/facade/RampSDK.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,29 @@ class RampSDK {
handleEvents()
}

fun startTransaction(activity: Activity, config: Config, callback: RampCallback) {
fun startTransaction(
activity: Activity,
config: Config,
callback: RampCallback,
url: String? = null
) {
Timber.d("RAMP SDK version - ${BuildConfig.VERSION}")
release()
this.callback = callback
val intent = Intent(activity, RampWidgetActivity::class.java)
intent.putExtra(
CONFIG_EXTRA, config
)
intent.putExtra(URL_EXTRA, url)
activity.startActivity(intent)
}

fun onOfframpCryptoSent(txHash: String? = null, error: String? = null) {
scope.launch {
EventBus.invokeEvent(SendCryptoResult(SendCryptoResultPayload(txHash, error)))
}
}

private fun handleEvents() {
scope.launch {
EventBus.events.collectLatest {
Expand All @@ -53,6 +66,25 @@ class RampSDK {
EventType.PURCHASE_FAILED -> {
callback?.onPurchaseFailed()
}

EventType.OFFRAMP_SALE_CREATED -> {
val payload = (it as OfframpSaleCreated).payload
callback?.onOfframpSaleCreated(
payload.sale,
payload.saleViewToken,
payload.apiUrl
)
}

EventType.SEND_CRYPTO -> {
val payload = (it as SendCrypto).payload
Timber.d("SEND CRYPTO : ${payload.address} ${payload.amount} ${payload.assetInfo}")
callback?.offrampSendCrypto(
assetInfo = payload.assetInfo,
amount = payload.amount,
address = payload.address
)
}
else -> {
Timber.w("Unhandled Event")
}
Expand All @@ -71,5 +103,6 @@ class RampSDK {

companion object {
internal const val CONFIG_EXTRA = "config"
internal const val URL_EXTRA = "url"
}
}
Loading

0 comments on commit c10f9e4

Please sign in to comment.