From e44cb5af2b36c283194adcd2efc1b3fac2b7bfcd Mon Sep 17 00:00:00 2001 From: Reece Williams <31943163+Reecepbcups@users.noreply.github.com> Date: Sat, 10 Feb 2024 00:16:02 -0600 Subject: [PATCH] 1 command testnet (standalone & IBC) (#18) * working imp * replace wasmd keys cmd * use path.Join * Validate, new project alias * alpha.2 globalfee * `make testnet-ibc` --- cmd/spawn/download-localic.go | 2 +- cmd/spawn/new-chain.go | 96 +++++++++++++++++++--------------- cmd/spawn/run.go | 2 - go.mod | 1 + go.sum | 2 + simapp/Makefile | 13 ++++- simapp/app/ante.go | 2 +- simapp/app/app.go | 3 +- simapp/chains/README.md | 6 +-- simapp/chains/ibc-testnet.json | 94 +++++++++++++++++++++++++++++++++ simapp/chains/testnet.json | 4 +- simapp/go.mod | 2 +- simapp/go.sum | 4 +- 13 files changed, 175 insertions(+), 56 deletions(-) create mode 100644 simapp/chains/ibc-testnet.json diff --git a/cmd/spawn/download-localic.go b/cmd/spawn/download-localic.go index cd8de33c..eda766de 100644 --- a/cmd/spawn/download-localic.go +++ b/cmd/spawn/download-localic.go @@ -74,7 +74,7 @@ var LocalICCmd = &cobra.Command{ } func whereIsLocalICInstalled() string { - for _, path := range []string{"local-ic", "bin/local-ic", "local-interchain/localic"} { + for _, path := range []string{"local-ic", path.Join("bin", "local-ic"), path.Join("local-interchain", "localic")} { if _, err := os.Stat(path); err == nil { return path } diff --git a/cmd/spawn/new-chain.go b/cmd/spawn/new-chain.go index a8ac939a..8d3301b5 100644 --- a/cmd/spawn/new-chain.go +++ b/cmd/spawn/new-chain.go @@ -7,6 +7,9 @@ import ( "path" "strings" + "golang.org/x/text/cases" + "golang.org/x/text/language" + "github.com/cosmos/btcutil/bech32" "github.com/spf13/cobra" "github.com/strangelove-ventures/simapp" @@ -27,6 +30,14 @@ type SpawnNewConfig struct { DisabledFeatures []string } +func (cfg *SpawnNewConfig) Validate() error { + if strings.ContainsAny(cfg.ProjectName, `~!@#$%^&*()_+{}|:"<>?/.,;'[]\=-`) { + return fmt.Errorf("project name cannot contain special characters %s", cfg.ProjectName) + } + + return nil +} + const ( FlagWalletPrefix = "bech32" FlagBinaryName = "bin" @@ -39,7 +50,7 @@ const ( var ( IgnoredFiles = []string{"embed.go", "heighliner/"} - SupportedFeatures = []string{"tokenfactory", "poa", "globalfee", "wasm", "ibc", "nft", "group", "circuit"} + SupportedFeatures = []string{"tokenfactory", "poa", "globalfee", "wasm", "icahost", "icacontroller"} ) func init() { @@ -51,18 +62,18 @@ func init() { newChain.Flags().Bool(FlagNoGit, false, "git init base") } -// TODO: reduce required inputs here. (or make them flags with defaults?) var newChain = &cobra.Command{ - Use: "new [project-name]", - Short: "List all current chains or outputs a current config information", - Example: fmt.Sprintf(`spawn new project --%s=cosmos --%s=appd`, FlagWalletPrefix, FlagBinaryName), + Use: "new-chain [project-name]", + Short: "Create a new project", + Example: fmt.Sprintf( + `spawn new rollchain --%s=cosmos --%s=appd --%s=token --%s=tokenfactory,poa,globalfee`, + FlagWalletPrefix, FlagBinaryName, FlagTokenDenom, FlagDisabled, + ), Args: cobra.ExactArgs(1), - // ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { - // return GetFiles(), cobra.ShellCompDirectiveNoFileComp - // }, + Aliases: []string{"new"}, Run: func(cmd *cobra.Command, args []string) { projName := strings.ToLower(args[0]) - appName := strings.Title(projName) + "App" + appName := cases.Title(language.AmericanEnglish).String(projName) + "App" walletPrefix, _ := cmd.Flags().GetString(FlagWalletPrefix) binName, _ := cmd.Flags().GetString(FlagBinaryName) @@ -74,7 +85,7 @@ var newChain = &cobra.Command{ ignoreGitInit, _ := cmd.Flags().GetBool(FlagNoGit) - cfg := SpawnNewConfig{ + cfg := &SpawnNewConfig{ ProjectName: projName, Bech32Prefix: walletPrefix, AppName: appName, @@ -86,12 +97,15 @@ var newChain = &cobra.Command{ // by default everything is on, then we remove what the user wants to disable DisabledFeatures: disabled, } + if err := cfg.Validate(); err != nil { + fmt.Println("Error validating config:", err) + return + } NewChain(cfg) // Create the base git repo if !ignoreGitInit { - // if git already exists, don't init if err := execCommand("git", "init", projName, "--quiet"); err != nil { fmt.Println("Error initializing git:", err) @@ -111,13 +125,14 @@ var newChain = &cobra.Command{ fmt.Printf("\n\n🎉 New blockchain '%s' generated!\n", projName) fmt.Println("🏅Getting started:") fmt.Println(" - $ cd " + projName) - fmt.Println(" - $ make testnet # build & start the testnet") + fmt.Println(" - $ make testnet # build & start a testnet") + fmt.Println(" - $ make testnet-ibc # build & start an ibc testnet") fmt.Printf(" - $ make install # build the %s binary\n", binName) fmt.Println(" - $ make local-image # build docker image") }, } -func NewChain(cfg SpawnNewConfig) { +func NewChain(cfg *SpawnNewConfig) { NewDirName := cfg.ProjectName bech32Prefix := cfg.Bech32Prefix projName := cfg.ProjectName @@ -176,7 +191,7 @@ func NewChain(cfg SpawnNewConfig) { return nil } - if relPath == "scripts/test_node.sh" { + if relPath == path.Join("scripts", "test_node.sh") { fc = strings.ReplaceAll(fc, "export BINARY=${BINARY:-wasmd}", fmt.Sprintf("export BINARY=${BINARY:-%s}", binaryName)) fc = strings.ReplaceAll(fc, "export DENOM=${DENOM:-token}", fmt.Sprintf("export DENOM=${DENOM:-%s}", cfg.TokenDenom)) } @@ -197,9 +212,11 @@ func NewChain(cfg SpawnNewConfig) { fc = strings.ReplaceAll(fc, "version.AppName=wasmd", fmt.Sprintf("version.AppName=%s", binaryName)) fc = strings.ReplaceAll(fc, "cmd/wasmd", fmt.Sprintf("cmd/%s", binaryName)) fc = strings.ReplaceAll(fc, "build/wasmd", fmt.Sprintf("build/%s", binaryName)) + fc = strings.ReplaceAll(fc, "wasmd keys", fmt.Sprintf("%s keys", binaryName)) // testnet // heighliner (not working atm) fc = strings.ReplaceAll(fc, "docker build . -t wasmd:local", fmt.Sprintf(`docker build . -t %s:local`, strings.ToLower(projName))) + // TODO: remember to make the below path.Join // fc = strings.ReplaceAll(fc, "heighliner build -c wasmd --local --dockerfile=cosmos -f chains.yaml", fmt.Sprintf(`heighliner build -c %s --local --dockerfile=cosmos -f chains.yaml`, strings.ToLower(appName))) // if strings.HasSuffix(relPath, "chains.yaml") { // fc = strings.ReplaceAll(fc, "myappname", strings.ToLower(appName)) @@ -253,24 +270,22 @@ func NewChain(cfg SpawnNewConfig) { // Removes disabled features from the files specified func removeDisabledFeatures(disabled []string, relativePath string, fileContent []byte) []byte { for _, name := range disabled { - switch name { - case "tokenfactory": + switch strings.ToLower(name) { + case "tokenfactory", "token-factory", "tf": fileContent = removeTokenFactory(relativePath, fileContent) case "poa": fileContent = removePoa(relativePath, fileContent) case "globalfee": fileContent = removeGlobalFee(relativePath, fileContent) - case "ibc": // this would remove all. Including PFM, then we can have others for specifics (i.e. ICAHost, IBCFees) - // fileContent = removeIbc(relativePath, fileContent) - continue - case "wasm": + case "wasm", "cosmwasm": fileContent = removeWasm(relativePath, fileContent) continue - case "nft": - // fileContent = removeNft(relativePath, fileContent) + case "icahost": + // what about all ICA? + // fileContent = removeICAHost(relativePath, fileContent) continue - case "circuit": - // fileContent = removeCircuit(relativePath, fileContent) + case "icacontroller": + // fileContent = removeICAController(relativePath, fileContent) continue } } @@ -287,11 +302,11 @@ func removeTokenFactory(relativePath string, fileContent []byte) []byte { fileContent = RemoveGoModImport("github.com/reecepbcups/tokenfactory", fileContent) } - if relativePath == "app/app.go" { + if relativePath == path.Join("app", "app.go") { fileContent = RemoveGeneralModule("tokenfactory", string(fileContent)) } - if relativePath == "scripts/test_node.sh" { + if relativePath == path.Join("scripts", "test_node.sh") { fileContent = RemoveGeneralModule("tokenfactory", string(fileContent)) } @@ -303,11 +318,11 @@ func removePoa(relativePath string, fileContent []byte) []byte { fileContent = RemoveGoModImport("github.com/strangelove-ventures/poa", fileContent) } - if relativePath == "app/app.go" || relativePath == "app/ante.go" { + if relativePath == path.Join("app", "app.go") || relativePath == path.Join("app", "ante.go") { fileContent = RemoveGeneralModule("poa", string(fileContent)) } - if relativePath == "scripts/test_node.sh" { + if relativePath == path.Join("scripts", "test_node.sh") { fileContent = RemoveGeneralModule("poa", string(fileContent)) } @@ -323,12 +338,12 @@ func removeGlobalFee(relativePath string, fileContent []byte) []byte { fileContent = RemoveGoModImport("github.com/reecepbcups/globalfee", fileContent) } - if relativePath == "app/app.go" || relativePath == "app/ante.go" { + if relativePath == path.Join("app", "app.go") || relativePath == path.Join("app", "ante.go") { fileContent = RemoveGeneralModule("globalfee", string(fileContent)) fileContent = RemoveGeneralModule("GlobalFee", string(fileContent)) } - if relativePath == "scripts/test_node.sh" { + if relativePath == path.Join("scripts", "test_node.sh") { fileContent = RemoveGeneralModule("globalfee", string(fileContent)) } @@ -341,13 +356,12 @@ func removeWasm(relativePath string, fileContent []byte) []byte { // if strings.Contains(string(fileContent), "spawntag:wasm") {} fileContent = RemoveTaggedLines("wasm", string(fileContent), true) - // TODO: tokenfactory depends on wasm currently. if relativePath == "go.mod" || relativePath == "go.sum" { fileContent = RemoveGoModImport("github.com/CosmWasm/wasmd", fileContent) fileContent = RemoveGoModImport("github.com/CosmWasm/wasmvm", fileContent) } - if relativePath == "app/app.go" || relativePath == "app/ante.go" { + if relativePath == path.Join("app", "app.go") || relativePath == path.Join("app", "ante.go") { for _, w := range []string{ "WasmKeeper", "wasmtypes", "wasmStack", "wasmOpts", "TXCounterStoreService", "WasmConfig", @@ -358,45 +372,45 @@ func removeWasm(relativePath string, fileContent []byte) []byte { } - if relativePath == "app/ante.go" { + if relativePath == path.Join("app", "ante.go") { fileContent = RemoveGeneralModule("wasm", string(fileContent)) } - if relativePath == "app/encoding.go" { + if relativePath == path.Join("app", "encoding.go") { fileContent = RemoveGeneralModule("wasmkeeper", string(fileContent)) } - if relativePath == "app/sim_test.go" { + if relativePath == path.Join("app", "sim_test.go") { fileContent = RemoveGeneralModule("wasm", string(fileContent)) } - if relativePath == "app/app_test.go" { + if relativePath == path.Join("app", "app_test.go") { fileContent = RemoveGeneralModule("wasmOpts", string(fileContent)) fileContent = RemoveGeneralModule("wasmkeeper", string(fileContent)) } - if relativePath == "app/test_support.go" { + if relativePath == path.Join("app", "test_support.go") { fileContent = RemoveGeneralModule("wasm", string(fileContent)) } - if relativePath == "app/test_helpers.go" { + if relativePath == path.Join("app", "test_helpers.go") { for _, w := range []string{"emptyWasmOptions", "wasmkeeper", "WasmOpts", "wasmOpts"} { fileContent = RemoveGeneralModule(w, string(fileContent)) } } - if relativePath == "app/wasm.go" { + if relativePath == path.Join("app", "wasm.go") { fileContent = []byte("REMOVE") } - if relativePath == "cmd/wasmd/commands.go" { + if relativePath == path.Join("cmd", "wasmd", "commands.go") { for _, w := range []string{"wasm", "wasmOpts", "wasmcli", "wasmtypes"} { fileContent = RemoveGeneralModule(w, string(fileContent)) } } - if relativePath == "cmd/wasmd/root.go" { + if relativePath == path.Join("cmd", "wasmd", "root.go") { for _, w := range []string{"wasmtypes", "wasmkeeper"} { fileContent = RemoveGeneralModule(w, string(fileContent)) } diff --git a/cmd/spawn/run.go b/cmd/spawn/run.go index e5dda27c..cbe326c0 100644 --- a/cmd/spawn/run.go +++ b/cmd/spawn/run.go @@ -12,8 +12,6 @@ import ( // heighliner build latest. // check if local-ic is found in path, if not, tell the user to download & move to their GOPATH (or do automatically) // if local-ic is installed, call it here automatically - -// TODO: maybe instead we just use local-ic directly? This could just be a builder for docker var BuildAppImage = &cobra.Command{ Use: "docker-build", Short: "Build Docker Image for your app", diff --git a/go.mod b/go.mod index 2bdbedc7..14207835 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/schollz/progressbar/v3 v3.14.1 github.com/spf13/cobra v1.8.0 github.com/strangelove-ventures/simapp v0.0.0-00000000-000000000000 + golang.org/x/text v0.14.0 ) require ( diff --git a/go.sum b/go.sum index 16325bca..7c77fbf1 100644 --- a/go.sum +++ b/go.sum @@ -34,6 +34,8 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/simapp/Makefile b/simapp/Makefile index 0a4b0227..5a886b2e 100644 --- a/simapp/Makefile +++ b/simapp/Makefile @@ -225,4 +225,15 @@ endif ### testnet ### ############################################################################### -testnet: install local-image +setup-testnet: install local-image +# import keys from testnet.json into test keyring + -`echo "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" | wasmd keys add acc0 --recover` + -`echo "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise" | wasmd keys add acc1 --recover` + +testnet: setup-testnet + spawn local-ic start testnet + +testnet-ibc: setup-testnet + spawn local-ic start ibc-testnet + +.PHONY: testnet testnet-ibc \ No newline at end of file diff --git a/simapp/app/ante.go b/simapp/app/ante.go index 2af5418e..989b5781 100644 --- a/simapp/app/ante.go +++ b/simapp/app/ante.go @@ -37,7 +37,7 @@ type HandlerOptions struct { GlobalFeeKeeper globalfeekeeper.Keeper BypassMinFeeMsgTypes []string - StakingKeeper stakingkeeper.Keeper // TODO: save the bond denom instead + StakingKeeper *stakingkeeper.Keeper // TODO: save the bond denom instead } // NewAnteHandler constructor diff --git a/simapp/app/app.go b/simapp/app/app.go index 94d92da9..6675b6d0 100644 --- a/simapp/app/app.go +++ b/simapp/app/app.go @@ -154,7 +154,6 @@ import ( const appName = "WasmApp" -// We pull these out so we can set them with LDFLAGS in the Makefile var ( NodeDir = ".wasmd" Bech32Prefix = "wasm" @@ -950,7 +949,7 @@ func NewChainApp( GlobalFeeKeeper: app.GlobalFeeKeeper, BypassMinFeeMsgTypes: GetDefaultBypassFeeMessages(), //spawntag:globalfee - StakingKeeper: *app.StakingKeeper, //spawntag:globalfee + StakingKeeper: app.StakingKeeper, //spawntag:globalfee }, ) if err != nil { diff --git a/simapp/chains/README.md b/simapp/chains/README.md index ea1608bc..ef5e070b 100644 --- a/simapp/chains/README.md +++ b/simapp/chains/README.md @@ -1,8 +1,8 @@ # Local Interchain Configurations -INSTALL: `spawn ...` - -RUN: `ICTEST_HOME=. local-ic start testnet` +RUN: +- `make testnet` *(full setup: docker image, binary, keys, and testnet start)* +- `spawn local-ic start testnet` *(Standalone start)* DOCS: TODO: diff --git a/simapp/chains/ibc-testnet.json b/simapp/chains/ibc-testnet.json new file mode 100644 index 00000000..832934f4 --- /dev/null +++ b/simapp/chains/ibc-testnet.json @@ -0,0 +1,94 @@ +{ + "chains": [ + { + "name": "appName", + "ibc_paths": ["ibc-connection-1"], + "chain_id": "chainid-1", + "denom": "mydenom", + "binary": "wasmd", + "bech32_prefix": "wasm", + "docker_image": { + "repository": "wasmd", + "version": "local" + }, + "gas_prices": "0mydenom", + "chain_type": "cosmos", + "coin_type": 118, + "trusting_period": "336h", + "gas_adjustment": 1.5, + "number_vals": 1, + "number_node": 0, + "debugging": true, + "block_time": "1000ms", + "host_port_override": { + "26657": "26657", + "1317": "1317", + "9090": "9090" + }, + "encoding-options": ["wasm", "tokenfactory"], + "config_file_overrides": [ + { + "file": "config/config.toml", + "paths": { + "moniker": "localvalmoniker", + "rpc.cors_allowed_origins": ["*"] + } + } + ], + "genesis": { + "modify": [ + { + "key": "app_state.gov.params.voting_period", + "value": "15s" + }, + { + "key": "app_state.gov.params.expedited_voting_period", + "value": "10s" + }, + { + "key": "app_state.gov.params.max_deposit_period", + "value": "15s" + }, + { + "key": "app_state.gov.params.min_deposit.0.denom", + "value": "mydenom" + }, + { + "key": "app_state.gov.params.min_deposit.0.amount", + "value": "1" + } + ], + "accounts": [ + { + "name": "acc0", + "address": "wasm1hj5fveer5cjtn4wd6wstzugjfdxzl0xpvsr89g", + "amount": "10000000000mydenom", + "mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" + }, + { + "name": "acc1", + "address": "wasm1efd63aw40lxf3n4mhf7dzhjkr453axursysrvp", + "amount": "10000000000mydenom", + "mnemonic": "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise" + } + ], + "startup_commands": [] + } + }, + { + "name": "terra", + "chain_id": "localterra-1", + "binary": "terrad", + "bech32_prefix": "terra", + "denom": "uluna", + "docker_image": { + "version": "v2.3.4" + }, + "block_time": "6s", + "encoding-options": ["wasm"], + "gas_prices": "0uluna", + "gas_adjustment": 2.0, + "ibc_paths": ["ibc-connection-1"] + } + ] +} \ No newline at end of file diff --git a/simapp/chains/testnet.json b/simapp/chains/testnet.json index 02dfda13..1f3ded93 100644 --- a/simapp/chains/testnet.json +++ b/simapp/chains/testnet.json @@ -61,13 +61,13 @@ { "name": "acc0", "address": "wasm1hj5fveer5cjtn4wd6wstzugjfdxzl0xpvsr89g", - "amount": "10000000000%DENOM%", + "amount": "10000000000mydenom", "mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" }, { "name": "acc1", "address": "wasm1efd63aw40lxf3n4mhf7dzhjkr453axursysrvp", - "amount": "10000000000%DENOM%", + "amount": "10000000000mydenom", "mnemonic": "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise" } ], diff --git a/simapp/go.mod b/simapp/go.mod index b81003f2..af625b2e 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -45,7 +45,7 @@ require ( github.com/cosmos/ibc-go/modules/capability v1.0.0 github.com/cosmos/ibc-go/v8 v8.0.0 github.com/prometheus/client_golang v1.17.0 - github.com/reecepbcups/globalfee v0.0.1-alpha.1 + github.com/reecepbcups/globalfee v0.0.1-alpha.2 github.com/reecepbcups/tokenfactory v0.50.0-alpha.2 github.com/spf13/cast v1.6.0 github.com/spf13/cobra v1.8.0 diff --git a/simapp/go.sum b/simapp/go.sum index 3a5e7dfe..79eeb232 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -1622,8 +1622,8 @@ github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3c github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/reecepbcups/globalfee v0.0.1-alpha.1 h1:h41zn4xRuFoSUhu0cDb337e9ysc0Yz+UNiAjJFGOtbw= -github.com/reecepbcups/globalfee v0.0.1-alpha.1/go.mod h1:Isr+lsp/0XBa9TZvLASyXqqgVWRTH7AOk9Nj1hto/Qc= +github.com/reecepbcups/globalfee v0.0.1-alpha.2 h1:9PUN/v7Kkcq+AKVOhIQKNCTZWp6CI2DdZx8EMqSqXcg= +github.com/reecepbcups/globalfee v0.0.1-alpha.2/go.mod h1:Isr+lsp/0XBa9TZvLASyXqqgVWRTH7AOk9Nj1hto/Qc= github.com/reecepbcups/tokenfactory v0.50.0-alpha.2 h1:rJYsEhd8h9pNgWX7Qntd7krRssd90KMZ9dKvbOohO7I= github.com/reecepbcups/tokenfactory v0.50.0-alpha.2/go.mod h1:qPchGcgRjxe1b6rnQOl+Rr2ruZmq8T4FcRBuLEuPICo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=