diff --git a/AGENTS.md b/AGENTS.md index 8c2c292..3ca5208 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -303,7 +303,7 @@ These are exported via the `elementBadge(el abiparser.Element) string` helper in ### Table output (non-TUI) -The `TablePrinter` in `pkg/abiparser/print.go` also uses Lip Gloss for the static `abi view --output table` command. Follow the same column-sizing pattern and the same colour palette. The `table*Style` vars there mirror the TUI palette — keep them in sync if colours change. +The `TablePrinter` in `pkg/abiparser/print.go` uses Lip Gloss for the static `abi view` command (default output is `table`; use `--output json` for JSON). Columns: **Type**, **Name**, **Inputs**, **Outputs**, **Selector/Topic**, **StateMutability**. Options `--with-input-name` and `--with-output-name` expand parameter names. Follow the same column-sizing pattern and the same colour palette. The `table*Style` vars there mirror the TUI palette — keep them in sync if colours change. ## Running / building diff --git a/README.md b/README.md index f98f1ee..b896a37 100644 --- a/README.md +++ b/README.md @@ -177,11 +177,14 @@ abitool abi list --chainid 84532 # 0x808456652fdb597867f38412077A9182bf77359F ⚠ FiatTokenProxy true # 0xd74cc5d436923b8ba2c179b4bCA2841D8A52C5B5 FiatTokenV2_2 true -# View as coloured table with selectors -abitool abi view -o table 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 +# View as coloured table with selectors (default) +abitool abi view 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 # Show parameter names too -abitool abi view -o table --with-input-name 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 +abitool abi view --with-input-name --with-output-name 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 + +# View as JSON +abitool abi view -o json 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 # Filter to events only abitool abi view -o table -t event 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 @@ -247,9 +250,10 @@ abitool encode --output json 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 transfer | Flag | Default | Description | |---|---|---| -| `-o, --output` | `json` | Output format: `json` or `table` | +| `-o, --output` | `table` | Output format: `json` or `table` | | `-t, --type` | `all` | Filter by type: `all`, `function`, `event`, `constructor`, `fallback`, `receive` | -| `--with-input-name` | `false` | Show parameter names in table output | +| `--with-input-name` | `false` | Show input parameter names in table output | +| `--with-output-name` | `false` | Show output parameter names in table output | ### `rpc` flags diff --git a/cmd/abitool/abi/view.go b/cmd/abitool/abi/view.go index a43421b..099b27b 100644 --- a/cmd/abitool/abi/view.go +++ b/cmd/abitool/abi/view.go @@ -11,9 +11,10 @@ import ( ) func init() { - ViewCmd.Flags().StringP("output", "o", "json", "Output format: json or table") + ViewCmd.Flags().StringP("output", "o", "table", "Output format: json or table") ViewCmd.Flags().StringP("type", "t", "all", "Filter by function type: all, function, event, constructor, fallback, receive") ViewCmd.Flags().Bool("with-input-name", false, "Display input parameter names in table output") + ViewCmd.Flags().Bool("with-output-name", false, "Display output parameter names in table output") if err := viper.BindPFlag("abi-view-output", ViewCmd.Flags().Lookup("output")); err != nil { panic(err) @@ -24,6 +25,9 @@ func init() { if err := viper.BindPFlag("abi-view-with-intput-name", ViewCmd.Flags().Lookup("with-input-name")); err != nil { panic(err) } + if err := viper.BindPFlag("abi-view-with-output-name", ViewCmd.Flags().Lookup("with-output-name")); err != nil { + panic(err) + } } // viewCmd displays a contract's ABI by its address. diff --git a/internal/contract/display.go b/internal/contract/display.go index 16e413b..52367e0 100644 --- a/internal/contract/display.go +++ b/internal/contract/display.go @@ -75,10 +75,14 @@ func Print(abi *abiparser.ABI) (string, error) { case "json": abiPrinter = abiparser.NewPrettyPrinter(&filtered) case "table": - abiPrinter = abiparser.NewTablePrinter(&filtered) + var opts []abiparser.TableOption if viper.GetBool("abi-view-with-intput-name") { - abiPrinter = abiparser.NewTablePrinter(&filtered, abiparser.WithInputNames()) + opts = append(opts, abiparser.WithInputNames()) } + if viper.GetBool("abi-view-with-output-name") { + opts = append(opts, abiparser.WithOutputNames()) + } + abiPrinter = abiparser.NewTablePrinter(&filtered, opts...) default: return "", fmt.Errorf("unsupported ABI print format: %s", viper.GetString("abi-print-format")) } diff --git a/pkg/abiparser/print.go b/pkg/abiparser/print.go index 3ad536b..be712aa 100644 --- a/pkg/abiparser/print.go +++ b/pkg/abiparser/print.go @@ -31,6 +31,7 @@ var ( tableMutDefaultStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#6272A4")) tableNameStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#F8F8F2")) tableInputStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#8BE9FD")) + tableOutputStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#50FA7B")) ) type PrettyPrinter struct { @@ -78,21 +79,28 @@ func (p *PrettyPrinter) Print() (string, error) { } // TablePrinter prints the ABI in a table format. -// The columns are: Type, Name, Inputs, StateMutability +// The columns are: Type, Name, Inputs, Outputs, Selector/Topic, StateMutability type TablePrinter struct { - a *ABI - WithInputNames bool + a *ABI + WithInputNames bool + WithOutputNames bool } -type tableOptions func(*TablePrinter) +type TableOption func(*TablePrinter) -func WithInputNames() tableOptions { +func WithInputNames() TableOption { return func(tp *TablePrinter) { tp.WithInputNames = true } } -func NewTablePrinter(abi *ABI, opts ...tableOptions) *TablePrinter { +func WithOutputNames() TableOption { + return func(tp *TablePrinter) { + tp.WithOutputNames = true + } +} + +func NewTablePrinter(abi *ABI, opts ...TableOption) *TablePrinter { table := &TablePrinter{a: abi} for _, opt := range opts { @@ -109,14 +117,15 @@ func (p *TablePrinter) Print() (string, error) { var b bytes.Buffer - headers := []string{"Type", "Name", "Inputs", "Selector/Topic", "StateMutability"} - colWidths := []int{len(headers[0]), len(headers[1]), len(headers[2]), len(headers[3]), len(headers[4])} + headers := []string{"Type", "Name", "Inputs", "Outputs", "Selector/Topic", "StateMutability"} + colWidths := []int{len(headers[0]), len(headers[1]), len(headers[2]), len(headers[3]), len(headers[4]), len(headers[5])} // Collect raw (unstyled) rows to measure column widths. type rawRow struct { typ string name string inputs string + outputs string selector string mut string } @@ -145,10 +154,11 @@ func (p *TablePrinter) Print() (string, error) { typ: string(element.Type), name: element.Name, inputs: p.formatInputTypes(element.Inputs), + outputs: p.formatOutputTypes(element.Outputs), selector: id, mut: string(element.StateMutability), } - cells := []string{r.typ, r.name, r.inputs, r.selector, r.mut} + cells := []string{r.typ, r.name, r.inputs, r.outputs, r.selector, r.mut} for i, c := range cells { if len(c) > colWidths[i] { colWidths[i] = len(c) @@ -184,8 +194,9 @@ func (p *TablePrinter) Print() (string, error) { b.WriteString(cell(styledType(r.typ), colWidths[0])) b.WriteString(cell(tableNameStyle.Render(r.name), colWidths[1])) b.WriteString(cell(tableInputStyle.Render(r.inputs), colWidths[2])) - b.WriteString(cell(styledSelector(r.selector), colWidths[3])) - b.WriteString(cell(styledMutability(r.mut), colWidths[4])) + b.WriteString(cell(tableOutputStyle.Render(r.outputs), colWidths[3])) + b.WriteString(cell(styledSelector(r.selector), colWidths[4])) + b.WriteString(cell(styledMutability(r.mut), colWidths[5])) b.WriteByte('\n') } @@ -243,3 +254,22 @@ func (p *TablePrinter) formatInputTypes(inputs []Input) string { return fmt.Sprintf("(%s)", strings.Join(types, ",")) } + +func (p *TablePrinter) formatOutputTypes(outputs []Output) string { + types := []string{} + + for _, out := range outputs { + if p.WithOutputNames && out.Name != "" { + types = append(types, fmt.Sprintf("%s %s", out.Name, out.Type)) + continue + } + + types = append(types, out.Type) + } + + if len(types) == 0 { + return "" + } + + return fmt.Sprintf("(%s)", strings.Join(types, ",")) +}