Skip to main content

Smart Checkout

Smart Checkout provides the functionality to calculate different options for a user to fund their wallet before completing their buy, swap or cancel actions. The funding routes can be used to craft a better checkout experience by guiding the user to top up their balance to be able to complete their desired actions.


💡Geo-location restrictions
The swap UI may not be available in certain jurisdictions in development and production environments. This currently includes, United States, Australia and other jurisdictions subject to Immutable's compliance controls. Note the UI is available in all locations in a sandbox environment for testing purposes only.

How it works

Purchasing an asset requires the user to have enough tokens to fill the order as well as having enough IMX to pay the gas fees associated with the transactions. During the checkout process, there may be an ERC20 token approval transaction as well as the order fulfillment transaction. Smart Checkout takes out all the work from having to calculate the total transaction costs, and suggests funding routes for how a user can get enough of the tokens they need to complete their purchase.

note

Smart checkout considers whether the Swap feature is enabled and is available for the user's region before suggesting founding routes for them.

Here are a couple of examples:

A simple swap example

  1. At checkout time, a user may not have enough of token A to make the purchase, but they have more than the equivalent amount in token B.
  2. Smart Checkout will provide options for the user to swap their tokens before completing the purchase, taking into account all gas fees that need to be covered.

User needs IMX to pay gas fees

  1. At checkout time a user may be low on IMX and cannot pay the gas fees to complete the purchase.
  2. Smart Checkout will provide options for the user to onramp IMX using their fiat currency or alternatively if they have IMX on layer 1 it will suggest a bridge.

Getting funding routes using Smart Checkout

To get the funding routes using Checkout SDK call the smartCheckout() method. If the user doesn't have enough funds to fulfil the purchase they will receive funding routes. The parameters for this method are listed below:

ParameterDescription
providerThe provider used to sign transactions.
itemRequirementsAn array of item requirements for the transaction. The array can contain item requirements of typeNativeItemRequirement, ERC20ItemRequirement, or ERC721ItemRequirement.
transactionOrGasAmountOptional parameter where you can provide a transaction or a gas amount. If nothing is provided, the gas calculation will be skipped.
routingOptionsOptional parameter to override which funding routes to consider. By default, all routes including swap, bridge and onramp will be considered.
onCompleteOptional parameter to provide a callback to be executed once all funding routes are found.
onFundingRouteOptional parameter to provide a callback to be executed on each funding route found.
fundingRouteFullAmountOptional parameter to flag whether to get funding routed based on full or partial amount. By default smart checkout processes partial amounts.

Call the checkout smart checkout method

import { checkout, config } from '@imtbl/sdk';
import { BigNumber } from 'ethers';

async function getFundingRoutes(orderId: string) {
// setup checkout instance, create provider and ensure connected
const checkoutSDK = new checkout.Checkout({
baseConfig: { environment: config.Environment.SANDBOX },
});
const { provider } = await checkoutSDK.createProvider({
walletProviderName: checkout.WalletProviderName.METAMASK,
});
const connectResult = await checkoutSDK.connect({ provider });

// call checkoutSDK.smartCheckout to get funding routes for a transaction
const fundingRoutes: checkout.SmartCheckoutResult =
await checkoutSDK.smartCheckout({
provider,
itemRequirements: [
{
type: checkout.ItemType.NATIVE,
amount: '1',
},
{
type: checkout.ItemType.ERC20,
amount: '2',
tokenAddress: '0x',
spenderAddress: '0x',
},
],
transactionOrGasAmount: {
type: checkout.TransactionOrGasType.GAS,
gasToken: {
type: checkout.GasTokenType.NATIVE,
limit: BigNumber.from('1'),
},
},
});

if (fundingRoutes.sufficient == true) {
// the transaction is sufficient and can be processed
}

if (fundingRoutes.sufficient == false) {
// the transaction is insufficient and requires more funds to be processed

const { routingOutcome } = fundingRoutes.router!;

if (routingOutcome.type === checkout.RoutingOutcomeType.ROUTES_FOUND) {
// there are ways to resolve the insufficient balance through the funding routes
routingOutcome.fundingRoutes.forEach((route) => {
// each route returned will have a list of steps to take
// to fund the users wallet with the amount they need
// of the token that they need
route.steps.forEach((step) => {
console.log({
type: step.type, // the step type to perform: bridge, swap, onramp
fundingItem: {
type: step.fundingItem.type, // the type of token needed
token: step.fundingItem.token, // token info of the item to bridge, swap or onramp
fundsRequired: step.fundingItem.fundsRequired, // how much the user needs to bridge, swap or onramp
userBalance: step.fundingItem.userBalance, // users balance of the item
},
});
});
});
} else if (
routingOutcome.type === checkout.RoutingOutcomeType.NO_ROUTES_FOUND
) {
// no possible swap/bridge/onramp funding routes were found for the transaction
}
}
}