Onchain.ERC20 (onchain v0.16.0)

Copy Markdown View Source

ERC-20 token operations.

Read operations are thin wrappers around Onchain.Contract.call/5. Write operations delegate to Onchain.Signer.send_transaction/3. Returns raw integer values for balances — consumers use Onchain.Decimal.to_decimal/2 with the result of decimals/2 to normalize.

Error Format

Errors pass through from underlying modules:

SourceError Shape
Onchain.Address.validate/1{:error, {:invalid_address, input}}
Onchain.Contract.call/5{:error, {:encode_error, ...}}, {:error, {:rpc_error, ...}}, {:error, {:decode_error, ...}}
Onchain.ABI.encode_hex_call/2{:error, {:encode_error, ...}}
Onchain.Signer.send_transaction/3{:error, {:missing_option, ...}}, {:error, {:sign_error, ...}}, etc.

Functions

FunctionPurpose
balance_of/3Token balance for a holder (raw integer)
balance_of!/3Same, raises on error
allowance/4Approved spending amount (raw integer)
allowance!/4Same, raises on error
decimals/2Token decimal places
decimals!/2Same, raises on error
symbol/2Token ticker symbol
symbol!/2Same, raises on error
approve/4Approve spender to transfer tokens (returns tx hash)
approve!/4Same, raises on error
transfer/4Transfer tokens to recipient (returns tx hash)
transfer!/4Same, raises on error

API Functions

FunctionArityDescriptionParam Kinds
call_trx3Run ABI-encoded ERC-20 calldata as a read-only eth_call.token: value, call_data: value, call_opts: value
exec_trx3Execute ABI-encoded ERC-20 calldata as a signed transaction.token: value, call_data: value, exec_opts: value
errors0Return the ERC-20 error signatures known to this wrapper.-
transfer!4Transfer tokens to a recipient. Raises on error.token: value, to: value, amount: value, opts: value
transfer4Transfer tokens to a recipient.token: value, to: value, amount: value, opts: value
approve!4Approve a spender to transfer tokens on your behalf. Raises on error.token: value, spender: value, amount: value, opts: value
approve4Approve a spender to transfer tokens on your behalf.token: value, spender: value, amount: value, opts: value
total_supply!2Get the total supply of a token. Raises on error.token: value, opts: value
total_supply2Get the total supply of a token.token: value, opts: value
symbol!2Get the ticker symbol of a token. Raises on error.token: value, opts: value
symbol2Get the ticker symbol of a token.token: value, opts: value
decimals!2Get the number of decimal places for a token. Raises on error.token: value, opts: value
decimals2Get the number of decimal places for a token.token: value, opts: value
allowance!4Get the approved spending amount. Raises on error.token: value, owner: value, spender: value, opts: value
allowance4Get the amount an owner has approved a spender to transfer.token: value, owner: value, spender: value, opts: value
balance_of!3Get the token balance of an address. Raises on error.token: value, holder: value, opts: value
balance_of3Get the token balance of an address.token: value, holder: value, opts: value

Summary

Functions

Get the amount an owner has approved a spender to transfer.

Get the approved spending amount. Raises on error.

Approve a spender to transfer tokens on your behalf.

Approve a spender to transfer tokens on your behalf. Raises on error.

Get the token balance of an address.

Get the token balance of an address. Raises on error.

Performs an eth_call against the given ERC-20 token with the provided ABI-encoded call_data and zero value/gas. Returns the call's return data without sending a transaction. call_opts is forwarded to Onchain.RPC.call_trx/2 with this module's known error signatures merged in.

Get the number of decimal places for a token.

Get the number of decimal places for a token. Raises on error.

Returns a list of known error codes (ABI signatures), which can be used when parsing error messages from contract calls.

Executes a transaction against the given ERC-20 token, using the provided ABI-encoded call_data. The configured Cartouche signer signs and submits the transaction; exec_opts is forwarded to Onchain.RPC.execute_trx/3 with this module's known error signatures merged in.

Get the ticker symbol of a token.

Get the ticker symbol of a token. Raises on error.

Get the total supply of a token.

Get the total supply of a token. Raises on error.

Transfer tokens to a recipient.

Transfer tokens to a recipient. Raises on error.

Types

call_opts()

@type call_opts() :: Keyword.t()

exec_opts()

@type exec_opts() :: Keyword.t()

Functions

allowance(token, owner, spender, opts \\ [])

@spec allowance(
  String.t() | binary(),
  String.t() | binary(),
  String.t() | binary(),
  keyword()
) ::
  {:ok, non_neg_integer()} | {:error, term()}

Get the amount an owner has approved a spender to transfer.

Parameters

  • token - ERC-20 token contract address (value)
  • owner - Token owner address (value)
  • spender - Approved spender address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Approved spending amount as raw integer ({:ok, non_neg_integer()} | {:error, term()})

# descripex:contract
%{
  params: %{
    owner: %{description: "Token owner address", kind: :value},
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    spender: %{description: "Approved spender address", kind: :value}
  },
  returns: %{
    type: "{:ok, non_neg_integer()} | {:error, term()}",
    description: "Approved spending amount as raw integer",
    example: "0"
  }
}

allowance!(token, owner, spender, opts \\ [])

@spec allowance!(
  String.t() | binary(),
  String.t() | binary(),
  String.t() | binary(),
  keyword()
) ::
  non_neg_integer()

Get the approved spending amount. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • owner - Token owner address (value)
  • spender - Approved spender address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Approved spending amount (non_neg_integer)

# descripex:contract
%{
  params: %{
    owner: %{description: "Token owner address", kind: :value},
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    spender: %{description: "Approved spender address", kind: :value}
  },
  returns: %{type: :non_neg_integer, description: "Approved spending amount"}
}

approve(token, spender, amount, opts)

@spec approve(
  String.t() | binary(),
  String.t() | binary(),
  non_neg_integer(),
  keyword()
) ::
  {:ok, String.t()} | {:error, term()}

Approve a spender to transfer tokens on your behalf.

Parameters

  • token - ERC-20 token contract address (value)
  • spender - Address to approve for spending (value)
  • amount - Amount to approve (raw integer, not decimal-adjusted) (value)
  • opts - Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas (value)

Returns

Transaction hash hex string ({:ok, String.t()} | {:error, term()})

# descripex:contract
%{
  params: %{
    opts: %{
      description: "Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    amount: %{
      description: "Amount to approve (raw integer, not decimal-adjusted)",
      kind: :value
    },
    spender: %{description: "Address to approve for spending", kind: :value}
  },
  returns: %{
    type: "{:ok, String.t()} | {:error, term()}",
    description: "Transaction hash hex string"
  }
}

approve!(token, spender, amount, opts)

@spec approve!(
  String.t() | binary(),
  String.t() | binary(),
  non_neg_integer(),
  keyword()
) :: String.t()

Approve a spender to transfer tokens on your behalf. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • spender - Address to approve for spending (value)
  • amount - Amount to approve (raw integer, not decimal-adjusted) (value)
  • opts - Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas (value)

Returns

Transaction hash hex string (string)

# descripex:contract
%{
  params: %{
    opts: %{
      description: "Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    amount: %{
      description: "Amount to approve (raw integer, not decimal-adjusted)",
      kind: :value
    },
    spender: %{description: "Address to approve for spending", kind: :value}
  },
  returns: %{type: :string, description: "Transaction hash hex string"}
}

balance_of(token, holder, opts \\ [])

@spec balance_of(String.t() | binary(), String.t() | binary(), keyword()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Get the token balance of an address.

Parameters

  • token - ERC-20 token contract address (value)
  • holder - Address to check balance for (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Raw token balance (use decimals/2 + Onchain.Decimal.to_decimal/2 to normalize) ({:ok, non_neg_integer()} | {:error, term()})

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    holder: %{description: "Address to check balance for", kind: :value}
  },
  returns: %{
    type: "{:ok, non_neg_integer()} | {:error, term()}",
    description: "Raw token balance (use decimals/2 + Onchain.Decimal.to_decimal/2 to normalize)",
    example: "1000000"
  }
}

balance_of!(token, holder, opts \\ [])

@spec balance_of!(String.t() | binary(), String.t() | binary(), keyword()) ::
  non_neg_integer()

Get the token balance of an address. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • holder - Address to check balance for (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Raw token balance (non_neg_integer)

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    holder: %{description: "Address to check balance for", kind: :value}
  },
  returns: %{type: :non_neg_integer, description: "Raw token balance"}
}

call_trx(token, call_data, call_opts)

@spec call_trx(Onchain.Configuration.contract(), binary(), call_opts()) :: term()

Performs an eth_call against the given ERC-20 token with the provided ABI-encoded call_data and zero value/gas. Returns the call's return data without sending a transaction. call_opts is forwarded to Onchain.RPC.call_trx/2 with this module's known error signatures merged in.

decimals(token, opts \\ [])

@spec decimals(String.t() | binary(), keyword()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Get the number of decimal places for a token.

Parameters

  • token - ERC-20 token contract address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Token decimal places (e.g. 6 for USDC, 18 for DAI) ({:ok, non_neg_integer()} | {:error, term()})

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value}
  },
  returns: %{
    type: "{:ok, non_neg_integer()} | {:error, term()}",
    description: "Token decimal places (e.g. 6 for USDC, 18 for DAI)",
    example: "6"
  }
}

decimals!(token, opts \\ [])

@spec decimals!(String.t() | binary(), keyword()) :: non_neg_integer()

Get the number of decimal places for a token. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Token decimal places (non_neg_integer)

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value}
  },
  returns: %{type: :non_neg_integer, description: "Token decimal places"}
}

errors()

@spec errors() :: [String.t()]

Returns a list of known error codes (ABI signatures), which can be used when parsing error messages from contract calls.

exec_trx(token, call_data, exec_opts)

@spec exec_trx(Onchain.Configuration.contract(), binary(), exec_opts()) ::
  {:ok, binary()} | {:error, term()}

Executes a transaction against the given ERC-20 token, using the provided ABI-encoded call_data. The configured Cartouche signer signs and submits the transaction; exec_opts is forwarded to Onchain.RPC.execute_trx/3 with this module's known error signatures merged in.

symbol(token, opts \\ [])

@spec symbol(String.t() | binary(), keyword()) :: {:ok, String.t()} | {:error, term()}

Get the ticker symbol of a token.

Parameters

  • token - ERC-20 token contract address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Token symbol string ({:ok, String.t()} | {:error, term()})

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value}
  },
  returns: %{
    type: "{:ok, String.t()} | {:error, term()}",
    description: "Token symbol string",
    example: "\"USDC\""
  }
}

symbol!(token, opts \\ [])

@spec symbol!(String.t() | binary(), keyword()) :: String.t()

Get the ticker symbol of a token. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Token symbol string (string)

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value}
  },
  returns: %{type: :string, description: "Token symbol string"}
}

total_supply(token, opts \\ [])

@spec total_supply(String.t() | binary(), keyword()) ::
  {:ok, non_neg_integer()} | {:error, term()}

Get the total supply of a token.

Parameters

  • token - ERC-20 token contract address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Raw total supply (use decimals/2 + Onchain.Decimal.to_decimal/2 to normalize) ({:ok, non_neg_integer()} | {:error, term()})

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value}
  },
  returns: %{
    type: "{:ok, non_neg_integer()} | {:error, term()}",
    description: "Raw total supply (use decimals/2 + Onchain.Decimal.to_decimal/2 to normalize)",
    example: "1000000000000"
  }
}

total_supply!(token, opts \\ [])

@spec total_supply!(String.t() | binary(), keyword()) :: non_neg_integer()

Get the total supply of a token. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • opts - Options: :rpc_url, :timeout, :block (default: [], value)

Returns

Raw total supply (non_neg_integer)

# descripex:contract
%{
  params: %{
    opts: %{
      default: [],
      description: "Options: :rpc_url, :timeout, :block",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value}
  },
  returns: %{type: :non_neg_integer, description: "Raw total supply"}
}

transfer(token, to, amount, opts)

@spec transfer(
  String.t() | binary(),
  String.t() | binary(),
  non_neg_integer(),
  keyword()
) ::
  {:ok, String.t()} | {:error, term()}

Transfer tokens to a recipient.

Parameters

  • token - ERC-20 token contract address (value)
  • to - Recipient address (value)
  • amount - Amount to transfer (raw integer, not decimal-adjusted) (value)
  • opts - Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas (value)

Returns

Transaction hash hex string ({:ok, String.t()} | {:error, term()})

# descripex:contract
%{
  params: %{
    opts: %{
      description: "Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    to: %{description: "Recipient address", kind: :value},
    amount: %{
      description: "Amount to transfer (raw integer, not decimal-adjusted)",
      kind: :value
    }
  },
  returns: %{
    type: "{:ok, String.t()} | {:error, term()}",
    description: "Transaction hash hex string"
  }
}

transfer!(token, to, amount, opts)

@spec transfer!(
  String.t() | binary(),
  String.t() | binary(),
  non_neg_integer(),
  keyword()
) ::
  String.t()

Transfer tokens to a recipient. Raises on error.

Parameters

  • token - ERC-20 token contract address (value)
  • to - Recipient address (value)
  • amount - Amount to transfer (raw integer, not decimal-adjusted) (value)
  • opts - Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas (value)

Returns

Transaction hash hex string (string)

# descripex:contract
%{
  params: %{
    opts: %{
      description: "Required: :private_key, :nonce, :chain_id, :rpc_url. Optional: :gas_limit, :max_fee_per_gas, :max_priority_fee_per_gas",
      kind: :value
    },
    token: %{description: "ERC-20 token contract address", kind: :value},
    to: %{description: "Recipient address", kind: :value},
    amount: %{
      description: "Amount to transfer (raw integer, not decimal-adjusted)",
      kind: :value
    }
  },
  returns: %{type: :string, description: "Transaction hash hex string"}
}