github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/abis/handle_show.go (about) 1 package abisPkg 2 3 import ( 4 "errors" 5 "fmt" 6 "sort" 7 8 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/abi" 9 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/articulate" 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 13 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 14 ) 15 16 func (opts *AbisOptions) HandleShow(rCtx *output.RenderCtx) (err error) { 17 if len(opts.Addrs) > 1 && opts.Globals.Format == "json" { 18 return opts.HandleMany(rCtx) 19 } 20 21 fetchData := func(modelChan chan types.Modeler, errorChan chan error) { 22 functions, which, err := opts.LoadAbis(opts.Addrs, false /* known */) 23 if err != nil { 24 if errors.Is(err, rpc.ErrNotAContract) { 25 msg := fmt.Errorf("address %s is not a smart contract", which) 26 errorChan <- msg 27 // Report but don't quit processing 28 } else { 29 // Cancel on all other errors 30 errorChan <- err 31 rCtx.Cancel() 32 // } else if len(opts.ProxyFor) > 0 { 33 // TODO: We need to copy the proxied-to ABI to the proxy (replacing) 34 } 35 } 36 37 for _, f := range functions { 38 modelChan <- f 39 } 40 } 41 42 return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOpts()) 43 } 44 45 func (opts *AbisOptions) LoadAbis(addrs []string, loadKnown bool) ([]*types.Function, string, error) { 46 abiCache := articulate.NewAbiCache(opts.Conn, opts.Known) 47 for _, addr := range addrs { 48 address := base.HexToAddress(addr) 49 proxy := base.HexToAddress(opts.ProxyFor) 50 if !proxy.IsZero() { 51 address = proxy 52 } 53 err := abi.LoadAbi(opts.Conn, address, &abiCache.AbiMap) 54 if err != nil { 55 return []*types.Function{}, address.Hex(), err 56 } 57 } 58 59 names := abiCache.AbiMap.Keys() 60 sort.Strings(names) 61 62 var funcs = make([]*types.Function, 0, len(names)) 63 for _, name := range names { 64 f := abiCache.AbiMap.GetValue(name) 65 if f != nil { 66 funcs = append(funcs, f) 67 } 68 } 69 return funcs, "", nil 70 }