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:
| Source | Error 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
| Function | Purpose |
|---|---|
balance_of/3 | Token balance for a holder (raw integer) |
balance_of!/3 | Same, raises on error |
allowance/4 | Approved spending amount (raw integer) |
allowance!/4 | Same, raises on error |
decimals/2 | Token decimal places |
decimals!/2 | Same, raises on error |
symbol/2 | Token ticker symbol |
symbol!/2 | Same, raises on error |
approve/4 | Approve spender to transfer tokens (returns tx hash) |
approve!/4 | Same, raises on error |
transfer/4 | Transfer tokens to recipient (returns tx hash) |
transfer!/4 | Same, raises on error |
API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
call_trx | 3 | Run ABI-encoded ERC-20 calldata as a read-only eth_call. | token: value, call_data: value, call_opts: value |
exec_trx | 3 | Execute ABI-encoded ERC-20 calldata as a signed transaction. | token: value, call_data: value, exec_opts: value |
errors | 0 | Return the ERC-20 error signatures known to this wrapper. | - |
transfer! | 4 | Transfer tokens to a recipient. Raises on error. | token: value, to: value, amount: value, opts: value |
transfer | 4 | Transfer tokens to a recipient. | token: value, to: value, amount: value, opts: value |
approve! | 4 | Approve a spender to transfer tokens on your behalf. Raises on error. | token: value, spender: value, amount: value, opts: value |
approve | 4 | Approve a spender to transfer tokens on your behalf. | token: value, spender: value, amount: value, opts: value |
total_supply! | 2 | Get the total supply of a token. Raises on error. | token: value, opts: value |
total_supply | 2 | Get the total supply of a token. | token: value, opts: value |
symbol! | 2 | Get the ticker symbol of a token. Raises on error. | token: value, opts: value |
symbol | 2 | Get the ticker symbol of a token. | token: value, opts: value |
decimals! | 2 | Get the number of decimal places for a token. Raises on error. | token: value, opts: value |
decimals | 2 | Get the number of decimal places for a token. | token: value, opts: value |
allowance! | 4 | Get the approved spending amount. Raises on error. | token: value, owner: value, spender: value, opts: value |
allowance | 4 | Get the amount an owner has approved a spender to transfer. | token: value, owner: value, spender: value, opts: value |
balance_of! | 3 | Get the token balance of an address. Raises on error. | token: value, holder: value, opts: value |
balance_of | 3 | Get 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
Functions
@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"
}
}
@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"}
}
@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"
}
}
@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"}
}
@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"
}
}
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"}
}
@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.
@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"
}
}
@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"}
}
@spec errors() :: [String.t()]
Returns a list of known error codes (ABI signatures), which can be used when parsing error messages from contract calls.
@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.
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\""
}
}
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"}
}
@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"
}
}
@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"}
}
@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"
}
}
@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"}
}