Repository: onflow/flow-cli
Pull request #1584 (2024-05-09 19:30:48)

Misc interactive init changes
Closes:

- https://github.com/onflow/flow-cli/issues/1502
- https://github.com/onflow/flow-cli/issues/1503
- https://github.com/onflow/flow-cli/issues/1583

______

For contributor use:

- [ ] Targeted PR against `master` branch
- [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work
- [ ] Code follows the [standards mentioned here](https://github.com/onflow/flow-cli/blob/master/CONTRIBUTING.md#styleguides)
- [ ] Updated relevant documentation
- [ ] Re-reviewed `Files changed` in the Github PR explorer
- [ ] Added appropriate labels



Patch:
diff --git a/cmd/flow/main.go b/cmd/flow/main.go
index 63ac4f8d..3d5e08b9 100644
--- a/cmd/flow/main.go
+++ b/cmd/flow/main.go
@@ -87,7 +87,6 @@ func main() {
 	}
 
 	// quick commands
-	quick.InitCommand.AddToParent(cmd)
 	quick.DeployCommand.AddToParent(cmd)
 	quick.RunCommand.AddToParent(cmd)
 
diff --git a/go.mod b/go.mod
index 70765299..02bbf45b 100644
--- a/go.mod
+++ b/go.mod
@@ -16,12 +16,12 @@ require (
 	github.com/onflow/cadence-tools/lint v0.14.2
 	github.com/onflow/cadence-tools/test v0.14.7
 	github.com/onflow/fcl-dev-wallet v0.7.4
-	github.com/onflow/flixkit-go v1.1.3
+	github.com/onflow/flixkit-go v1.1.4-0.20240507174933-7a1de7bbf70f
 	github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f
 	github.com/onflow/flow-emulator v0.62.1
 	github.com/onflow/flow-go v0.33.2-0.20240412174857-015156b297b5
 	github.com/onflow/flow-go-sdk v0.46.3
-	github.com/onflow/flowkit v1.17.3
+	github.com/onflow/flowkit v1.17.4-0.20240507180449-b565ca87f6b8
 	github.com/onflowser/flowser/v3 v3.1.3
 	github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
 	github.com/pkg/errors v0.9.1
diff --git a/go.sum b/go.sum
index fb3856c2..a94ffa91 100644
--- a/go.sum
+++ b/go.sum
@@ -936,8 +936,8 @@ github.com/onflow/crypto v0.25.1 h1:0txy2PKPMM873JbpxQNbJmuOJtD56bfs48RQfm0ts5A=
 github.com/onflow/crypto v0.25.1/go.mod h1:C8FbaX0x8y+FxWjbkHy0Q4EASCDR9bSPWZqlpCLYyVI=
 github.com/onflow/fcl-dev-wallet v0.7.4 h1:vI6t3U0AO88R/Iitn5KsnniSpbN9Lqsqwvi9EJT4C0k=
 github.com/onflow/fcl-dev-wallet v0.7.4/go.mod h1:kc42jkiuoPJmxMRFjfbRO9XvnR/3XLheaOerxVMDTiw=
-github.com/onflow/flixkit-go v1.1.3 h1:td94mkklIwXvDP075D0eofPE04oKse24PxvFTyOvMJI=
-github.com/onflow/flixkit-go v1.1.3/go.mod h1:qOYI1l7r3gSPk6luTnk95ni020UeTY+E48GuB3Tl0xk=
+github.com/onflow/flixkit-go v1.1.4-0.20240507174933-7a1de7bbf70f h1:8UEBHYC6mgc2c7U3p2ZoC3R6gupn1oqU61/jURZTsjI=
+github.com/onflow/flixkit-go v1.1.4-0.20240507174933-7a1de7bbf70f/go.mod h1:KUk8ODCdwNYF8PBYdu+VBTTrZ1IPWKvVJsdsGsEAtA0=
 github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f h1:S8yIZw9LFXfYD1V5H9BiixihHw3GrXVPrmfplSzYaww=
 github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.4-0.20231016154253-a00dbf7c061f/go.mod h1:jM6GMAL+m0hjusUgiYDNrixPQ6b9s8xjoJQoEu5bHQI=
 github.com/onflow/flow-core-contracts/lib/go/templates v1.2.4-0.20231016154253-a00dbf7c061f h1:Ep+Mpo2miWMe4pjPGIaEvEzshRep30dvNgxqk+//FrQ=
@@ -957,8 +957,8 @@ github.com/onflow/flow-nft/lib/go/contracts v1.1.0/go.mod h1:YsvzYng4htDgRB9sa9j
 github.com/onflow/flow/protobuf/go/flow v0.2.2/go.mod h1:gQxYqCfkI8lpnKsmIjwtN2mV/N2PIwc1I+RUK4HPIc8=
 github.com/onflow/flow/protobuf/go/flow v0.4.0 h1:5TGmPwRmnSt7aawgtPGF9ehoGHHir9Cy9LVoAiU9t/E=
 github.com/onflow/flow/protobuf/go/flow v0.4.0/go.mod h1:NA2pX2nw8zuaxfKphhKsk00kWLwfd+tv8mS23YXO4Sk=
-github.com/onflow/flowkit v1.17.3 h1:0Fi3tLnieWOYq95A3ySk3TZ0GUPtKaX8ofssgve9e58=
-github.com/onflow/flowkit v1.17.3/go.mod h1:laapt1diM4Pbqt0dotKMH+LbUAOEqgugpH1p4+sPhcw=
+github.com/onflow/flowkit v1.17.4-0.20240507180449-b565ca87f6b8 h1:59gqw1cXdvyV+jYbItoqULLxcA1MWrTSzcSsgRIXEto=
+github.com/onflow/flowkit v1.17.4-0.20240507180449-b565ca87f6b8/go.mod h1:laapt1diM4Pbqt0dotKMH+LbUAOEqgugpH1p4+sPhcw=
 github.com/onflow/go-ethereum v1.13.4 h1:iNO86fm8RbBbhZ87ZulblInqCdHnAQVY8okBrNsTevc=
 github.com/onflow/go-ethereum v1.13.4/go.mod h1:cE/gEUkAffhwbVmMJYz+t1dAfVNHNwZCgc3BWtZxBGY=
 github.com/onflow/nft-storefront/lib/go/contracts v0.0.0-20221222181731-14b90207cead h1:2j1Unqs76Z1b95Gu4C3Y28hzNUHBix7wL490e61SMSw=
diff --git a/internal/accounts/create-interactive.go b/internal/accounts/create-interactive.go
index 3adc6008..3b94070f 100644
--- a/internal/accounts/create-interactive.go
+++ b/internal/accounts/create-interactive.go
@@ -54,7 +54,7 @@ func createInteractive(state *flowkit.State) (*accountResult, error) {
 	log := output.NewStdoutLogger(output.InfoLog)
 	name := prompt.AccountNamePrompt(state.Accounts().Names())
 	networkName, selectedNetwork := prompt.CreateAccountNetworkPrompt()
-	privateFile := accounts.PrivateKeyFile(name)
+	privateFile := accounts.PrivateKeyFile(name, "")
 
 	// create new gateway based on chosen network
 	gw, err := gateway.NewGrpcGateway(selectedNetwork)
diff --git a/internal/config/config.go b/internal/config/config.go
index 3689ca34..17835e7d 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -29,7 +29,7 @@ var Cmd = &cobra.Command{
 }
 
 func init() {
-	initCommand.AddToParent(Cmd)
+	//initCommand.AddToParent(Cmd)
 	Cmd.AddCommand(addCmd)
 	Cmd.AddCommand(removeCmd)
 }
diff --git a/internal/config/init.go b/internal/config/init.go
index a9015985..50c48eda 100644
--- a/internal/config/init.go
+++ b/internal/config/init.go
@@ -19,39 +19,32 @@
 package config
 
 import (
-	"bytes"
 	"fmt"
 	"os"
 
 	"github.com/onflow/flow-go-sdk/crypto"
-	"github.com/spf13/cobra"
-
 	"github.com/onflow/flowkit"
 	"github.com/onflow/flowkit/config"
-	"github.com/onflow/flowkit/output"
-
-	"github.com/onflow/flow-cli/internal/command"
-	"github.com/onflow/flow-cli/internal/util"
 )
 
-type flagsInit struct {
-	ServicePrivateKey  string `flag:"service-private-key" info:"Service account private key"`
-	ServiceKeySigAlgo  string `default:"ECDSA_P256" flag:"service-sig-algo" info:"Service account key signature algorithm"`
-	ServiceKeyHashAlgo string `default:"SHA3_256" flag:"service-hash-algo" info:"Service account key hash algorithm"`
-	Reset              bool   `default:"false" flag:"reset" info:"Reset configuration file"`
-	Global             bool   `default:"false" flag:"global" info:"Initialize global user configuration"`
-}
-
-var InitFlag = flagsInit{}
-
-var initCommand = &command.Command{
-	Cmd: &cobra.Command{
-		Use:   "init",
-		Short: "Initialize a new configuration",
-	},
-	Flags: &InitFlag,
-	Run:   Initialise,
-}
+//type flagsInit struct {
+//	ServicePrivateKey  string `flag:"service-private-key" info:"Service account private key"`
+//	ServiceKeySigAlgo  string `default:"ECDSA_P256" flag:"service-sig-algo" info:"Service account key signature algorithm"`
+//	ServiceKeyHashAlgo string `default:"SHA3_256" flag:"service-hash-algo" info:"Service account key hash algorithm"`
+//	Reset              bool   `default:"false" flag:"reset" info:"Reset configuration file"`
+//	Global             bool   `default:"false" flag:"global" info:"Initialize global user configuration"`
+//}
+//
+//var InitFlag = flagsInit{}
+
+//var initCommand = &command.Command{
+//	Cmd: &cobra.Command{
+//		Use:   "init",
+//		Short: "Initialize a new configuration",
+//	},
+//	Flags: &InitFlag,
+//	Run:   Initialise,
+//}
 
 // InitConfigParameters holds all necessary parameters for initializing the configuration.
 type InitConfigParameters struct {
@@ -64,7 +57,25 @@ type InitConfigParameters struct {
 }
 
 // InitializeConfiguration creates the Flow configuration json file based on the provided parameters.
-func InitializeConfiguration(params InitConfigParameters, logger output.Logger, readerWriter flowkit.ReaderWriter) (*flowkit.State, error) {
+func InitializeConfiguration(params InitConfigParameters, readerWriter flowkit.ReaderWriter) (*flowkit.State, error) {
+	var path string
+	if params.TargetDirectory != "" {
+		path = fmt.Sprintf("%s/flow.json", params.TargetDirectory)
+
+		// Create the directory if it doesn't exist
+		err := readerWriter.MkdirAll(params.TargetDirectory, os.ModePerm)
+		if err != nil {
+			return nil, fmt.Errorf("failed to create target directory: %w", err)
+		}
+	} else {
+		// Otherwise, choose between the default and global paths
+		if params.Global {
+			path = config.GlobalPath()
+		} else {
+			path = config.DefaultPath
+		}
+	}
+
 	sigAlgo := crypto.StringToSignatureAlgorithm(params.ServiceKeySigAlgo)
 	if sigAlgo == crypto.UnknownSignatureAlgorithm {
 		return nil, fmt.Errorf("invalid signature algorithm: %s", params.ServiceKeySigAlgo)
@@ -75,7 +86,7 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger,
 		return nil, fmt.Errorf("invalid hash algorithm: %s", params.ServiceKeyHashAlgo)
 	}
 
-	state, err := flowkit.Init(readerWriter, sigAlgo, hashAlgo)
+	state, err := flowkit.Init(readerWriter, sigAlgo, hashAlgo, params.TargetDirectory)
 	if err != nil {
 		return nil, err
 	}
@@ -89,24 +100,6 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger,
 		state.SetEmulatorKey(privateKey)
 	}
 
-	var path string
-	if params.TargetDirectory != "" {
-		path = fmt.Sprintf("%s/flow.json", params.TargetDirectory)
-
-		// Create the directory if it doesn't exist
-		err := state.ReaderWriter().MkdirAll(params.TargetDirectory, os.ModePerm)
-		if err != nil {
-			return nil, fmt.Errorf("failed to create target directory: %w", err)
-		}
-	} else {
-		// Otherwise, choose between the default and global paths
-		if params.Global {
-			path = config.GlobalPath()
-		} else {
-			path = config.DefaultPath
-		}
-	}
-
 	if config.Exists(path) && !params.Reset {
 		return nil, fmt.Errorf(
 			"configuration already exists at: %s, if you want to reset configuration use the reset flag",
@@ -114,61 +107,5 @@ func InitializeConfiguration(params InitConfigParameters, logger output.Logger,
 		)
 	}
 
-	err = state.Save(path)
-	if err != nil {
-		return nil, err
-	}
-
 	return state, nil
 }
-
-func Initialise(
-	_ []string,
-	_ command.GlobalFlags,
-	logger output.Logger,
-	readerWriter flowkit.ReaderWriter,
-	_ flowkit.Services,
-) (command.Result, error) {
-	params := InitConfigParameters{
-		ServicePrivateKey:  InitFlag.ServicePrivateKey,
-		ServiceKeySigAlgo:  InitFlag.ServiceKeySigAlgo,
-		ServiceKeyHashAlgo: InitFlag.ServiceKeyHashAlgo,
-		Reset:              InitFlag.Reset,
-		Global:             InitFlag.Global,
-	}
-	state, err := InitializeConfiguration(params, logger, readerWriter)
-	if err != nil {
-		return nil, err
-	}
-
-	return &InitResult{State: state}, nil
-}
-
-type InitResult struct {
-	*flowkit.State
-}
-
-func (r *InitResult) JSON() any {
-	return r
-}
-
-func (r *InitResult) String() string {
-	var b bytes.Buffer
-	writer := util.CreateTabWriter(&b)
-	account, _ := r.State.EmulatorServiceAccount()
-
-	_, _ = fmt.Fprintf(writer, "Configuration initialized\n")
-	_, _ = fmt.Fprintf(writer, "Service account: %s\n\n", output.Bold("0x"+account.Address.String()))
-	_, _ = fmt.Fprintf(writer,
-		"Start emulator by running: %s \nReset configuration using: %s\n",
-		output.Bold("'flow emulator'"),
-		output.Bold("'flow init --reset'"),
-	)
-
-	_ = writer.Flush()
-	return b.String()
-}
-
-func (r *InitResult) Oneliner() string {
-	return ""
-}
diff --git a/internal/emulator/start.go b/internal/emulator/start.go
index 1608d42c..38420aad 100644
--- a/internal/emulator/start.go
+++ b/internal/emulator/start.go
@@ -62,7 +62,7 @@ func configuredServiceKey(
 			hashAlgo = emulator.DefaultServiceKeyHashAlgo
 		}
 
-		state, err = flowkit.Init(loader, sigAlgo, hashAlgo)
+		state, err = flowkit.Init(loader, sigAlgo, hashAlgo, "")
 		if err != nil {
 			exitf(1, err.Error())
 		} else {
diff --git a/internal/prompt/select-options.go b/internal/prompt/select-options.go
index 747a37c7..a1732873 100644
--- a/internal/prompt/select-options.go
+++ b/internal/prompt/select-options.go
@@ -82,7 +82,7 @@ func (m optionSelectModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 func (m optionSelectModel) View() string {
 	var b strings.Builder
 	b.WriteString(fmt.Sprintf("%s\n", m.message))
-	b.WriteString("Use arrow keys to navigate, space to select, enter to confirm, q to quit:\n\n")
+	b.WriteString("Use arrow keys to navigate, space to select, enter to confirm or skip, q to quit:\n\n")
 	for i, choice := range m.choices {
 		if m.cursor == i {
 			b.WriteString("> ")
diff --git a/internal/quick/init.go b/internal/quick/init.go
index 4f9c3df5..ca00f073 100644
--- a/internal/quick/init.go
+++ b/internal/quick/init.go
@@ -18,22 +18,15 @@
 
 package quick
 
-import (
-	"github.com/spf13/cobra"
-
-	"github.com/onflow/flow-cli/internal/command"
-	"github.com/onflow/flow-cli/internal/config"
-)
-
 // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error
 
-var InitCommand = &command.Command{
-	Cmd: &cobra.Command{
-		Use:     "init",
-		Short:   "Initialize a new configuration",
-		Example: "flow project init",
-		GroupID: "project",
-	},
-	Flags: &config.InitFlag,
-	Run:   config.Initialise, // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error
-}
+//var InitCommand = &command.Command{
+//	Cmd: &cobra.Command{
+//		Use:     "init",
+//		Short:   "Initialize a new configuration",
+//		Example: "flow project init",
+//		GroupID: "project",
+//	},
+//	Flags: &config.InitFlag,
+//	Run:   config.Initialise, // TODO(sideninja) workaround - init needed to be copied in order to work else there is flag duplicate error
+//}
diff --git a/internal/super/generate.go b/internal/super/generate.go
index 590bf608..3fb04f3c 100644
--- a/internal/super/generate.go
+++ b/internal/super/generate.go
@@ -109,7 +109,7 @@ func generateContract(
 	_ flowkit.Services,
 	state *flowkit.State,
 ) (result command.Result, err error) {
-	generator := NewGenerator(DefaultCadenceDirectory, state, logger, false)
+	generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true)
 	contract := Contract{Name: args[0], Account: args[1]}
 	err = generator.Create(TemplateMap{ContractType: []TemplateItem{contract}})
 	return nil, err
@@ -122,7 +122,7 @@ func generateTransaction(
 	_ flowkit.Services,
 	state *flowkit.State,
 ) (result command.Result, err error) {
-	generator := NewGenerator(DefaultCadenceDirectory, state, logger, false)
+	generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true)
 	transaction := OtherTemplate{Name: args[0]}
 	err = generator.Create(TemplateMap{TransactionType: []TemplateItem{transaction}})
 	return nil, err
@@ -135,7 +135,7 @@ func generateScript(
 	_ flowkit.Services,
 	state *flowkit.State,
 ) (result command.Result, err error) {
-	generator := NewGenerator(DefaultCadenceDirectory, state, logger, false)
+	generator := NewGenerator(DefaultCadenceDirectory, state, logger, false, true)
 	script := OtherTemplate{Name: args[0]}
 	err = generator.Create(TemplateMap{ScriptType: []TemplateItem{script}})
 	return nil, err
@@ -186,14 +186,16 @@ type Generator struct {
 	state       *flowkit.State
 	logger      output.Logger
 	disableLogs bool
+	saveState   bool
 }
 
-func NewGenerator(directory string, state *flowkit.State, logger output.Logger, disableLogs bool) *Generator {
+func NewGenerator(directory string, state *flowkit.State, logger output.Logger, disableLogs, saveState bool) *Generator {
 	return &Generator{
 		directory:   directory,
 		state:       state,
 		logger:      logger,
 		disableLogs: disableLogs,
+		saveState:   saveState,
 	}
 }
 
@@ -327,9 +329,12 @@ func (g *Generator) updateContractsState(name, location string) error {
 	}
 
 	g.state.Contracts().AddOrUpdate(contract)
-	err := g.state.SaveDefault()
-	if err != nil {
-		return fmt.Errorf("error saving to flow.json: %w", err)
+
+	if g.saveState {
+		err := g.state.SaveDefault() // TODO: Support adding a target project directory
+		if err != nil {
+			return fmt.Errorf("error saving to flow.json: %w", err)
+		}
 	}
 
 	return nil
diff --git a/internal/super/setup.go b/internal/super/setup.go
index 6089aa8b..d28b9131 100644
--- a/internal/super/setup.go
+++ b/internal/super/setup.go
@@ -25,7 +25,6 @@ import (
 	"os"
 	"path/filepath"
 
-	"github.com/onflow/flow-go-sdk/crypto"
 	"github.com/spf13/afero"
 
 	"github.com/onflow/flow-cli/internal/util"
@@ -59,9 +58,10 @@ type flagsSetup struct {
 
 var setupFlags = flagsSetup{}
 
+// TODO: Add --config-only flag
 var SetupCommand = &command.Command{
 	Cmd: &cobra.Command{
-		Use:     "setup <project name>",
+		Use:     "init <project name>",
 		Short:   "Start a new Flow project",
 		Example: "flow setup my-project",
 		Args:    cobra.MaximumNArgs(1),
@@ -111,10 +111,10 @@ func startInteractiveSetup(
 	rw := afero.Afero{
 		Fs: afero.NewOsFs(),
 	}
-	state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256)
-	if err != nil {
-		return "", err
-	}
+	//state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256)
+	//if err != nil {
+	//	return "", err
+	//}
 
 	// Ask for project name if not given
 	if len(args) < 1 {
@@ -153,7 +153,7 @@ func startInteractiveSetup(
 		Global:             false,
 		TargetDirectory:    tempDir,
 	}
-	state, err = config.InitializeConfiguration(params, logger, state.ReaderWriter())
+	state, err := config.InitializeConfiguration(params, rw)
 	if err != nil {
 		return "", fmt.Errorf("failed to initialize configuration: %w", err)
 	}
@@ -168,7 +168,7 @@ func startInteractiveSetup(
 
 	templates := TemplateMap{
 		"contract": []TemplateItem{
-			Contract{Name: "DefaultContract", Account: "example-account"},
+			Contract{Name: "DefaultContract", Account: ""},
 		},
 		"script": []TemplateItem{
 			OtherTemplate{Name: "DefaultScripts"},
@@ -178,7 +178,7 @@ func startInteractiveSetup(
 		},
 	}
 
-	generator := NewGenerator(directoryPath, state, logger, true)
+	generator := NewGenerator(directoryPath, state, logger, true, false)
 	err = generator.Create(templates)
 	if err != nil {
 		return "", err
@@ -186,7 +186,7 @@ func startInteractiveSetup(
 
 	// Prompt to ask which core contracts should be installed
 	sc := systemcontracts.SystemContractsForChain(flowGo.Mainnet)
-	promptMessage := "Select the core contracts you'd like to install:"
+	promptMessage := "Select any core contracts you would like to install or skip to continue."
 
 	contractNames := make([]string, 0)
 
@@ -215,6 +215,7 @@ func startInteractiveSetup(
 		}
 	}
 
+	logger.Info("")
 	logger.Info(util.MessageWithEmojiPrefix("🔄", "Installing selected core contracts and dependencies..."))
 
 	// Add the selected core contracts as dependencies
@@ -284,8 +285,9 @@ func (s *setupResult) String() string {
 	out.WriteString(fmt.Sprintf("%s Congrats! your project was created.\n\n", output.SuccessEmoji()))
 	out.WriteString("Start development by following these steps:\n")
 	out.WriteString(fmt.Sprintf("1. '%s' to change to your new project,\n", output.Bold(fmt.Sprintf("cd %s", relDir))))
-	out.WriteString(fmt.Sprintf("2. '%s' or run Flowser to start the emulator,\n", output.Bold("flow emulator")))
-	out.WriteString(fmt.Sprintf("3. '%s' to start developing.\n\n", output.Bold("flow dev")))
+	//out.WriteString(fmt.Sprintf("2. '%s' or run Flowser to start the emulator,\n", output.Bold("flow emulator")))
+	out.WriteString(fmt.Sprintf("2. '%s' to start developing.\n", output.Bold("flow dev")))
+	out.WriteString(fmt.Sprintf("3. '%s' to test your project.\n\n", output.Bold("flow test")))
 	out.WriteString(fmt.Sprintf("You should also read README.md to learn more about the development process!\n"))
 
 	return out.String()


Test patch:
diff --git a/internal/cadence/lint_test.go b/internal/cadence/lint_test.go
index 99d025b5..0759c6f6 100644
--- a/internal/cadence/lint_test.go
+++ b/internal/cadence/lint_test.go
@@ -311,7 +311,7 @@ func setupMockState(t *testing.T) *flowkit.State {
 	}`), 0644)
 
 	rw := afero.Afero{Fs: mockFs}
-	state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256)
+	state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256, "")
 	require.NoError(t, err)
 
 	// Mock flowkit contracts
diff --git a/internal/super/flix_test.go b/internal/super/flix_test.go
index b8215c14..4a5e8325 100644
--- a/internal/super/flix_test.go
+++ b/internal/super/flix_test.go
@@ -221,7 +221,7 @@ func Test_GenerateFlixPrefill(t *testing.T) {
 	var rw = afero.Afero{Fs: mockFS}
 	err := rw.WriteFile(cadenceFile, []byte(CADENCE_SCRIPT), 0644)
 	assert.NoError(t, err)
-	state, _ := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256)
+	state, _ := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256, "")
 
 	mockFlixService := new(MockFlixService)
 	ctx := context.Background()
diff --git a/internal/super/generate_test.go b/internal/super/generate_test.go
index f1f6f2b7..5f799e63 100644
--- a/internal/super/generate_test.go
+++ b/internal/super/generate_test.go
@@ -34,7 +34,7 @@ func TestGenerateNewContract(t *testing.T) {
 	logger := output.NewStdoutLogger(output.NoneLog)
 	_, state, _ := util.TestMocks(t)
 
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 
 	// Test contract generation
 	err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}})
@@ -72,7 +72,7 @@ access(all) fun testContract() {
 	assert.Equal(t, expectedTestContent, util.NormalizeLineEndings(string(testContent)))
 
 	// Test file already exists scenario
-	generatorTwo := NewGenerator("cadence", state, logger, false)
+	generatorTwo := NewGenerator("cadence", state, logger, false, true)
 	err = generatorTwo.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}})
 	assert.Error(t, err)
 	expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc"))
@@ -83,7 +83,7 @@ func TestGenerateContractWithAccount(t *testing.T) {
 	logger := output.NewStdoutLogger(output.NoneLog)
 	_, state, _ := util.TestMocks(t)
 
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 
 	// Test contract generation
 	err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: "example-account"}}})
@@ -104,7 +104,7 @@ func TestGenerateNewContractSkipTests(t *testing.T) {
 
 	generateFlags.SkipTests = true
 
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 	t.Cleanup(func() {
 		generateFlags.SkipTests = false
 	})
@@ -127,7 +127,7 @@ func TestGenerateNewContractWithCDCExtension(t *testing.T) {
 	_, state, _ := util.TestMocks(t)
 
 	// Test contract generation
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 	err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "Tester.cdc", Account: ""}}})
 	assert.NoError(t, err, "Failed to generate contract")
 
@@ -145,7 +145,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) {
 	_, state, _ := util.TestMocks(t)
 
 	// Test contract generation
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 	err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}})
 	assert.NoError(t, err, "Failed to generate contract")
 
@@ -155,7 +155,7 @@ func TestGenerateNewContractFileAlreadyExists(t *testing.T) {
 	assert.NotNil(t, content)
 
 	// Test file already exists scenario
-	generatorTwo := NewGenerator("cadence", state, logger, false)
+	generatorTwo := NewGenerator("cadence", state, logger, false, true)
 	err = generatorTwo.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}})
 	assert.Error(t, err)
 	expectedError := fmt.Sprintf("file already exists: %s", filepath.FromSlash("cadence/contracts/TestContract.cdc"))
@@ -166,7 +166,7 @@ func TestGenerateNewContractWithFileExtension(t *testing.T) {
 	logger := output.NewStdoutLogger(output.NoneLog)
 	_, state, _ := util.TestMocks(t)
 
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 	err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract.cdc", Account: ""}}})
 	assert.NoError(t, err, "Failed to generate contract")
 
@@ -180,7 +180,7 @@ func TestGenerateNewScript(t *testing.T) {
 	logger := output.NewStdoutLogger(output.NoneLog)
 	_, state, _ := util.TestMocks(t)
 
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 	err := generator.Create(TemplateMap{"script": []TemplateItem{OtherTemplate{Name: "TestScript"}}})
 	assert.NoError(t, err, "Failed to generate contract")
 
@@ -199,7 +199,7 @@ func TestGenerateNewTransaction(t *testing.T) {
 	logger := output.NewStdoutLogger(output.NoneLog)
 	_, state, _ := util.TestMocks(t)
 
-	generator := NewGenerator("cadence", state, logger, false)
+	generator := NewGenerator("cadence", state, logger, false, true)
 	err := generator.Create(TemplateMap{"transaction": []TemplateItem{OtherTemplate{Name: "TestTransaction"}}})
 	assert.NoError(t, err, "Failed to generate contract")
 
@@ -219,7 +219,7 @@ func TestGenerateNewWithDirFlag(t *testing.T) {
 	logger := output.NewStdoutLogger(output.NoneLog)
 	_, state, _ := util.TestMocks(t)
 
-	generator := NewGenerator("customDir", state, logger, false)
+	generator := NewGenerator("customDir", state, logger, false, true)
 	err := generator.Create(TemplateMap{"contract": []TemplateItem{Contract{Name: "TestContract", Account: ""}}})
 	assert.NoError(t, err, "Failed to generate contract")
 
diff --git a/internal/util/test.go b/internal/util/test.go
index 9f5be372..189b4f1c 100644
--- a/internal/util/test.go
+++ b/internal/util/test.go
@@ -39,7 +39,7 @@ var TestID = flow.HexToID("24993fc99f81641c45c0afa307e683b4f08d407d90041aa9439f4
 func TestMocks(t *testing.T) (*mocks.MockServices, *flowkit.State, flowkit.ReaderWriter) {
 	services := mocks.DefaultMockServices()
 	rw, _ := tests.ReaderWriter()
-	state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256)
+	state, err := flowkit.Init(rw, crypto.ECDSA_P256, crypto.SHA3_256, "")
 	require.NoError(t, err)
 
 	return services, state, rw