Skip to main content
Runtime functions allow you to use values that are resolved at execution time rather than when building the instruction. Essential for handling unknown swap outputs, bridge results, and composable flows.

runtimeERC20BalanceOf

Inject the ERC-20 token balance of an address at execution time.
import { runtimeERC20BalanceOf } from "@biconomy/abstractjs";

const balance = runtimeERC20BalanceOf(options);

Parameters

ParameterTypeRequiredDescription
tokenAddressAddressYesToken contract address
targetAddressAddressYesAddress to check balance of
constraintsConstraint[]NoExecution constraints

Returns

RuntimeValue - Can be used as argument in buildComposable

Example

import { runtimeERC20BalanceOf, greaterThanOrEqualTo } from "@biconomy/abstractjs";

// Transfer entire USDC balance
const transfer = await account.buildComposable({
  type: "transfer",
  data: {
    chainId: 8453,
    tokenAddress: USDC,
    recipient: userAddress,
    amount: runtimeERC20BalanceOf({
      tokenAddress: USDC,
      targetAddress: account.addressOn(8453, true),
      constraints: [greaterThanOrEqualTo(1n)]
    })
  }
});

runtimeNativeBalanceOf

Inject the native token (ETH) balance of an address at execution time.
import { runtimeNativeBalanceOf } from "@biconomy/abstractjs";

const balance = runtimeNativeBalanceOf(options);

Parameters

ParameterTypeRequiredDescription
targetAddressAddressYesAddress to check balance of
constraintsConstraint[]NoExecution constraints

Example

import { runtimeNativeBalanceOf } from "@biconomy/abstractjs";

// Send all ETH
const sendAll = await account.buildComposable({
  type: "nativeTokenTransfer",
  data: {
    chainId: 8453,
    to: recipient,
    value: runtimeNativeBalanceOf({
      targetAddress: account.addressOn(8453, true)
    })
  }
});

runtimeERC20AllowanceOf

Inject the ERC-20 allowance between two addresses at execution time.
import { runtimeERC20AllowanceOf } from "@biconomy/abstractjs";

const allowance = runtimeERC20AllowanceOf(options);

Parameters

ParameterTypeRequiredDescription
ownerAddressYesToken owner address
spenderAddressYesSpender address
tokenAddressAddressYesToken contract address
constraintsConstraint[]NoExecution constraints

Example

const transferFrom = await account.buildComposable({
  type: "default",
  data: {
    chainId: 8453,
    to: USDC,
    abi: erc20Abi,
    functionName: "transferFrom",
    args: [
      owner,
      recipient,
      runtimeERC20AllowanceOf({
        owner,
        spender: account.addressOn(8453, true),
        tokenAddress: USDC
      })
    ]
  }
});

runtimeParamViaCustomStaticCall

Inject any return value from a view function (up to 32 bytes).
import { runtimeParamViaCustomStaticCall } from "@biconomy/abstractjs";

const value = runtimeParamViaCustomStaticCall(options);

Parameters

ParameterTypeRequiredDescription
targetContractAddressAddressYesContract to call
functionAbiAbiYesABI containing function
functionNamestringYesFunction name
argsany[]YesFunction arguments

Example

const dynamicRecipient = runtimeParamViaCustomStaticCall({
  targetContractAddress: registry,
  functionAbi: registryAbi,
  functionName: "getRecipient",
  args: [userId]
});

const transfer = await account.buildComposable({
  type: "nativeTokenTransfer",
  data: {
    chainId: 8453,
    to: dynamicRecipient,
    value: parseEther("0.1")
  }
});

Constraints

Constraints control when instructions execute and protect against bad values.

greaterThanOrEqualTo

import { greaterThanOrEqualTo } from "@biconomy/abstractjs";

constraints: [greaterThanOrEqualTo(parseUnits("90", 6))]
Wait until value is ≥ threshold.

lessThanOrEqualTo

import { lessThanOrEqualTo } from "@biconomy/abstractjs";

constraints: [lessThanOrEqualTo(parseUnits("100", 6))]
Wait until value is ≤ threshold.

equalTo

import { equalTo } from "@biconomy/abstractjs";

constraints: [equalTo(expectedValue)]
Wait until value equals expected.

Constraint Behavior

Constraints determine execution order in multi-step flows:
// Step 1: Swap (executes first)
const swap = await account.buildComposable({ /* ... */ });

// Step 2: Deposit (waits for swap to complete)
const deposit = await account.buildComposable({
  type: "default",
  data: {
    args: [
      runtimeERC20BalanceOf({
        tokenAddress: WETH,
        targetAddress: account.addressOn(8453, true),
        constraints: [greaterThanOrEqualTo(minExpected)]  // Waits here
      })
    ]
  }
});
Flow:
  1. MEE attempts to execute deposit
  2. Constraint not satisfied (no WETH yet)
  3. MEE waits and retries
  4. Swap completes, WETH arrives
  5. Constraint satisfied → deposit executes

MEE Version Requirements

FunctionMinimum Version
runtimeERC20BalanceOfMEE v1.0.0
runtimeERC20AllowanceOfMEE v1.0.0
runtimeNativeBalanceOfMEE v2.2.0
runtimeParamViaCustomStaticCallMEE v2.2.0