Skip to content

Commit

Permalink
Improve Ethers.TxData module (#155)
Browse files Browse the repository at this point in the history
* Export `TxData.to_map/2` function in docs

* Move abi_decode to TxData module

* Update CHANGELOG.md
  • Loading branch information
alisinabh authored Dec 3, 2024
1 parent 0879345 commit 068c100
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

### Enhancements

- Move and export abi decode functionality to `Ethers.TxData` module
- Export `Ethers.TxData.to_map/2` in docs

## v0.5.4 (2024-10-22)

### Bug fixes
Expand Down
12 changes: 4 additions & 8 deletions lib/ethers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -661,14 +661,10 @@ defmodule Ethers do

defp pre_process(data, [], _action, _opts), do: {:ok, data}

defp post_process({:ok, resp}, %{selector: selector}, :call) when valid_result(resp) do
selector
|> ABI.decode(Ethers.Utils.hex_decode!(resp), :output)
|> Enum.zip(selector.returns)
|> Enum.map(fn {return, type} -> Utils.human_arg(return, type) end)
|> case do
[element] -> {:ok, element}
elements -> {:ok, elements}
defp post_process({:ok, resp}, %{selector: _selector} = tx_data, :call)
when valid_result(resp) do
with {:ok, data} <- Utils.hex_decode(resp) do
TxData.abi_decode(data, tx_data, :output)
end
end

Expand Down
35 changes: 34 additions & 1 deletion lib/ethers/tx_data.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ defmodule Ethers.TxData do
and the target `to` address.
"""

alias Ethers.Utils

@typedoc """
Holds transaction data, the function selector and the default `to` address.
Expand Down Expand Up @@ -31,8 +33,12 @@ defmodule Ethers.TxData do
}
end

@doc false
@doc """
Converts a TxData struct and optional overrides to a map ready for RPC data.
"""
@spec to_map(t() | map(), Keyword.t()) :: map()
def to_map(tx_data, overrides \\ [])

def to_map(%__MODULE__{} = tx_data, overrides) do
tx_data
|> get_tx_map()
Expand All @@ -48,6 +54,33 @@ defmodule Ethers.TxData do
end)
end

@doc """
ABI decodes a function input/output given a TxData or FunctionSelector
"""
@spec abi_decode(binary(), ABI.FunctionSelector.t() | t(), type :: :input | :output) ::
{:ok, any() | [any()]}
def abi_decode(data, tx_data_or_selector, type \\ :output)

def abi_decode(data, %{selector: %ABI.FunctionSelector{} = selector}, type),
do: abi_decode(data, selector, type)

def abi_decode(data, %ABI.FunctionSelector{} = selector, type) do
types =
case type do
:input -> selector.types
:output -> selector.returns
end

selector
|> ABI.decode(data, type)
|> Enum.zip(types)
|> Enum.map(fn {return, type} -> Utils.human_arg(return, type) end)
|> case do
[element] -> {:ok, element}
elements -> {:ok, elements}
end
end

defp get_tx_map(%{selector: %{type: :function}} = tx_data) do
%{data: tx_data.data}
|> maybe_add_to_address(tx_data.default_address)
Expand Down

0 comments on commit 068c100

Please sign in to comment.