github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/tokens/validate.go (about) 1 // Copyright 2021 The TrueBlocks Authors. All rights reserved. 2 // Use of this source code is governed by a license that can 3 // be found in the LICENSE file. 4 5 package tokensPkg 6 7 import ( 8 "errors" 9 10 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base" 11 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/config" 12 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc" 13 "github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate" 14 ) 15 16 func (opts *TokensOptions) validateTokens() error { 17 chain := opts.Globals.Chain 18 19 opts.testLog() 20 21 if opts.BadFlag != nil { 22 return opts.BadFlag 23 } 24 25 if !config.IsChainConfigured(chain) { 26 return validate.Usage("chain {0} is not properly configured.", chain) 27 } 28 29 err := validate.ValidateEnumSlice("--parts", opts.Parts, "[name|symbol|decimals|totalSupply|version|some|all]") 30 if err != nil { 31 return err 32 } 33 34 if opts.Changes { 35 return validate.Usage("The {0} option is not yet implemented.", "--changes") 36 } 37 38 if len(opts.Addrs) == 0 { 39 return validate.Usage("You must specify at least two address") 40 41 } else { 42 if opts.ByAcct { 43 if len(opts.Addrs) < 2 { 44 return validate.Usage("You must specify at least two addresses") 45 } 46 47 // all but the last is assumed to be a token 48 for _, addr := range opts.Addrs[:len(opts.Addrs)-1] { 49 err := opts.Conn.IsContractAtLatest(base.HexToAddress(addr)) 50 if err != nil { 51 if errors.Is(err, rpc.ErrNotAContract) { 52 return validate.Usage("The value {0} is not a token contract.", addr) 53 } 54 return err 55 } 56 } 57 } else { 58 // the first is assumed to be a smart contract, the rest can be either non-existant, another smart contract or an EOA 59 addr := opts.Addrs[0] 60 err := opts.Conn.IsContractAtLatest(base.HexToAddress(addr)) 61 if err != nil { 62 if errors.Is(err, rpc.ErrNotAContract) { 63 return validate.Usage("The value {0} is not a token contract.", addr) 64 } 65 return err 66 } 67 } 68 } 69 70 err = validate.ValidateAddresses(opts.Addrs) 71 if err != nil { 72 return err 73 } 74 75 // Blocks are optional, but if they are present, they must be valid 76 if len(opts.Blocks) > 0 { 77 bounds, err := validate.ValidateIdentifiersWithBounds( 78 chain, 79 opts.Blocks, 80 validate.ValidBlockIdWithRangeAndDate, 81 1, 82 &opts.BlockIds, 83 ) 84 85 if err != nil { 86 if invalidLiteral, ok := err.(*validate.InvalidIdentifierLiteralError); ok { 87 return invalidLiteral 88 } 89 90 if errors.Is(err, validate.ErrTooManyRanges) { 91 return validate.Usage("Specify only a single block range at a time.") 92 } 93 94 return err 95 } 96 97 latest := opts.Conn.GetLatestBlockNumber() 98 if bounds.First < (latest-250) && !opts.Conn.IsNodeArchive() { 99 return validate.Usage("The {0} requires {1}.", "query for historical state", "an archive node") 100 } 101 } 102 103 return opts.Globals.Validate() 104 }