github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/tokens/handle_parts.go (about) 1 package tokensPkg 2 3 import ( 4 "errors" 5 "fmt" 6 7 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 8 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/output" 9 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/tslib" 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/types" 11 "github.com/ethereum/go-ethereum" 12 ) 13 14 func (opts *TokensOptions) HandleParts(rCtx *output.RenderCtx) error { 15 chain := opts.Globals.Chain 16 fetchData := func(modelChan chan types.Modeler, errorChan chan error) { 17 for _, address := range opts.Addrs { 18 addr := base.HexToAddress(address) 19 currentBn := base.Blknum(0) 20 currentTs := base.Timestamp(0) 21 for _, br := range opts.BlockIds { 22 blockNums, err := br.ResolveBlocks(chain) 23 if err != nil { 24 errorChan <- err 25 if errors.Is(err, ethereum.NotFound) { 26 continue 27 } 28 rCtx.Cancel() 29 return 30 } 31 32 for _, bn := range blockNums { 33 if state, err := opts.Conn.GetTokenState(addr, fmt.Sprintf("0x%x", bn)); err != nil { 34 errorChan <- err 35 } else { 36 s := &types.Token{ 37 Address: state.Address, 38 BlockNumber: bn, 39 TotalSupply: state.TotalSupply, 40 Decimals: uint64(state.Decimals), 41 } 42 if opts.Globals.Verbose { 43 if bn == 0 || bn != currentBn { 44 currentTs, _ = tslib.FromBnToTs(chain, bn) 45 } 46 s.Timestamp = currentTs 47 currentBn = bn 48 } 49 modelChan <- s 50 } 51 } 52 } 53 } 54 } 55 56 extraOpts := map[string]any{ 57 "parts": opts.Parts, 58 "loadNames": true, 59 } 60 61 return output.StreamMany(rCtx, fetchData, opts.Globals.OutputOptsWithExtra(extraOpts)) 62 }