Skip to main content

Off-Ramp Native Flow Integration

Please read the general information about the Off-Ramp Native Flow before proceeding.

Web with SDK

To enable native flow, configure the widget with a useSendCryptoCallback parameter set to true.

You can subscribe to the SEND_CRYPTO event as mentioned here.

To submit the SEND_CRYPTO_RESULT event back to the widget you should use onSendCrypto method provided by the SDK.

Note: We recommend to use the built-in types provided with the SDK, but you can also review raw event payloads here.

iOS with SDK

To enable native flow, configure the widget with a useSendCryptoCallback parameter set to true.

Use delegate method to be notified about offramp sale:

public protocol RampDelegate {
// ...
func ramp(_ rampViewController: RampViewController, didCreateOfframpPurchase purchase: OfframpPurchase, _ purchaseViewToken: String, _ apiUrl: URL)
}

public struct OfframpPurchase: Decodable {
public let id: String
public let createdAt: String // ISO date-time string
public let crypto: Crypto
public let fiat: Fiat

public struct Crypto: Decodable {
public let amount: String
public let assetInfo: AssetInfo

public struct AssetInfo: Decodable {
public let address: String? // 0x-prefixed address for ERC-20 tokens, `null` for ETH
public let symbol: String // asset symbol, for example `ETH`, `DAI`, `USDC`
public let chain: String
public let type: String // asset type & network, e.g. `ETH`, `ERC20`, `MATIC_ERC20`
public let name: String
public let decimals: Int // token decimals, e.g. 18 for ETH/DAI, 6 for USDC
}
}

public struct Fiat: Decodable {
public let amount: Double
public let currencySymbol: String // description of the purchased asset (address, symbol, name, decimals)
}
}

Use delegate method to inform widget about the submitted crypto:

public protocol RampDelegate {
func ramp(_ rampViewController: RampViewController, didRequestOfframp payload: SendCryptoPayload, responseHandler: @escaping (SendCryptoResultPayload) -> Void)
}

public struct SendCryptoPayload: Decodable {
public let assetInfo: AssetInfo
public let amount: String
public let address: String
}

public struct SendCryptoResultPayload: Encodable {
let txHash: String?

public init(txHash: String? = nil) {
self.txHash = txHash
}
}

txHash: String - transaction hash (nullable)

Note: We recommend to use the built-in types provided with the SDK, but you can also review raw event payloads here.

Android with SDK

To enable native flow, configure the widget with a useSendCryptoCallback parameter set to true.

Implement onOfframpSaleCreated method in the RampCallback object, to be notified about the offramp transaction:

val callback = object : RampCallback {
...

fun onOfframpSaleCreated(
sale: OfframpSale,
saleViewToken: String,
apiUrl: String
){
...
}
}

Parameters:

data class OfframpPurchase(
val id: String,
val createdAt: String, // ISO date-time string
val crypto: Crypto,
val fiat: Fiat
)

data class Crypto(
val amount: String,
val assetInfo: Asset, // description of the purchased asset (address, symbol, name, decimals)
)

data class Fiat(
val amount: Double,
val currencySymbol: String, // description of the purchased asset (address, symbol, name, decimals)
)

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`
)

Use onOfframpCryptoSent method to inform widget about the submitted crypto:

onOfframpCryptoSent(txHash: String? = null, error: String? = null)

txHash: String - transaction hash (nullable) error: String - error message (nullable)

Example:

 rampSDK.onOfframpCryptoSent(txHash)

Note: We recommend to use the built-in types provided with the SDK, but you can also review raw event payloads here.

Non-SDK

It is possible to integrate native flow without the SDK. In order to do that:

  • make sure to use the webview (webview-desktop or webview-mobile) variant
  • specify the query param useSendCryptoCallbackVersion as 1 in the widget URL
  • handle window post-messages on your own

You can find our recommendations on the implementation and links to examples from our SDK below.

iOS without SDK

Recommended webview component:

WKWebView

Subscribing to events:

post-message events are sent by the widget to RampInstantMobile object. Example from the SDK.

Sending events to the widget:

could be done by invoking evaluateJavaScript method on webview instance and passing window.postMessage(STRINGIFIED_EVENT) script. Example from the SDK.

Android without SDK

Recommended webview component:

android.webkit.WebView

Subscribing to events:

post-message events are sent by the widget to RampInstantMobile object which could be configured by setupWebView function like in ramp-sdk-android.

Sending events to the widget:

could be done by calling post method on webview bindings. Example from the SDK

Native flow should be implemented on top of regular (off-ramp) integration.

Native Flow Details

The flow should progress as described:

  1. User: creates an off-ramp transaction as usual in the widget
    1. Widget: “send crypto” screen is presented with the dedicated Send with your wallet button
  2. User: clicks Send with your wallet button
  3. Widget: sends post-message event:
{
"eventVersion": 1,
"type": "SEND_CRYPTO",
"payload": {
"assetInfo": {
// AssetInfo object
"address": null, // string | null
"symbol": "ETH", // string
"chain": "ETH", // string
"type": "NATIVE", // string
"name": "Ether", // string
"decimals": 18 // number
},
"amount": "30000000000000000", // in wei
"address": "0x0000...." // receiver crypto wallet address
}
}
  1. Integrator: After receiving this event, integrator should present the user with an UI overlaid on top of the widget for sending the crypto. Alternatively, the widget could be temporarily hidden by the integrator.
  2. User: confirms the transaction in the integrator UI and the crypto is sent to the address provided in the event payload.
  3. Integrator: The widget should be presented again to the user (integrator UI should disappear or widget should be unhidden)
  4. Integrator: SEND_CRYPTO_RESULT event should be sent by the integrator to resume flow:
{
"eventVersion": 1,
"type": "SEND_CRYPTO_RESULT",
"payload": {
"txHash": "0x0000...." // string, transaction hash
}
}

or

{
"eventVersion": 1,
"type": "SEND_CRYPTO_RESULT",
"payload": {
"error": "error message" // string | undefined
}
}
  1. Widget: user is presented with the transaction summary, where they can access the transaction status page and close the widget (go back to the integrator app/page).