From 8040de5a7dd122021071759847779ce3f8d9e8c4 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 6 Jul 2023 10:23:56 -0700 Subject: [PATCH 01/30] Get flix by name --- internal/flix/flix.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 internal/flix/flix.go diff --git a/internal/flix/flix.go b/internal/flix/flix.go new file mode 100644 index 000000000..5606b28ef --- /dev/null +++ b/internal/flix/flix.go @@ -0,0 +1,32 @@ +package flix + +import ( + "fmt" + "io" + "log" + "net/http" +) + +func GetInteractionTemplateByName(templateName string) (string, error) { + baseUrl := "https://flix.flow.com/v1/templates" + url := fmt.Sprintf("%s?name=%s", baseUrl, templateName) + + resp, err := http.Get(url) + if err != nil { + return "", err + } + defer func() { + if err := resp.Body.Close(); err != nil { + log.Printf("Warning: error while closing the response body: %v", err) + } + }() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + + sb := string(body) + + return sb, nil +} From 207cbe73a34724caf0a60f733c8fdeb0b9641bb7 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 13 Jul 2023 13:25:00 -0700 Subject: [PATCH 02/30] Use flixkit library to execute flix scripts --- go.mod | 2 + internal/flix/flix.go | 32 ----------- internal/scripts/execute.go | 102 ++++++++++++++++++++++++++++++++---- 3 files changed, 95 insertions(+), 41 deletions(-) delete mode 100644 internal/flix/flix.go diff --git a/go.mod b/go.mod index 93fbab74d..5f960091f 100644 --- a/go.mod +++ b/go.mod @@ -147,6 +147,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onflow/atree v0.6.0 // indirect github.com/onflow/cadence-tools/lint v0.9.0 // indirect + github.com/onflow/flixkit-go v0.0.0 github.com/onflow/flow-archive v1.3.4-0.20230503192214-9e81e82d4dcc // indirect github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.3 // indirect github.com/onflow/flow-ft/lib/go/contracts v0.7.0 // indirect @@ -232,3 +233,4 @@ require ( ) replace github.com/onflow/flow-cli/flowkit => ./flowkit +replace github.com/onflow/flixkit-go => ../flixkit-go \ No newline at end of file diff --git a/internal/flix/flix.go b/internal/flix/flix.go deleted file mode 100644 index 5606b28ef..000000000 --- a/internal/flix/flix.go +++ /dev/null @@ -1,32 +0,0 @@ -package flix - -import ( - "fmt" - "io" - "log" - "net/http" -) - -func GetInteractionTemplateByName(templateName string) (string, error) { - baseUrl := "https://flix.flow.com/v1/templates" - url := fmt.Sprintf("%s?name=%s", baseUrl, templateName) - - resp, err := http.Get(url) - if err != nil { - return "", err - } - defer func() { - if err := resp.Body.Close(); err != nil { - log.Printf("Warning: error while closing the response body: %v", err) - } - }() - - body, err := io.ReadAll(resp.Body) - if err != nil { - return "", err - } - - sb := string(body) - - return sb, nil -} diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 41f82ce1b..a9c99f536 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -21,6 +21,9 @@ package scripts import ( "context" "fmt" + "strings" + + "github.com/onflow/flixkit-go" "github.com/onflow/cadence" flowsdk "github.com/onflow/flow-go-sdk" @@ -58,18 +61,24 @@ func execute( readerWriter flowkit.ReaderWriter, flow flowkit.Services, ) (command.Result, error) { - filename := args[0] + filenameOrAction := args[0] - code, err := readerWriter.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("error loading script file: %w", err) + fmt.Println("filename: ", filenameOrAction) + + if strings.HasPrefix(filenameOrAction, "flix") { + return executeFlixScript(args, filenameOrAction, readerWriter, flow) } - var scriptArgs []cadence.Value + return executeLocalScript(args, filenameOrAction, readerWriter, flow) +} + +func sendScript(code []byte, argsArr []string, location string, flow flowkit.Services) (command.Result, error) { + var cadenceArgs []cadence.Value + var err error if scriptFlags.ArgsJSON != "" { - scriptArgs, err = arguments.ParseJSON(scriptFlags.ArgsJSON) + cadenceArgs, err = arguments.ParseJSON(scriptFlags.ArgsJSON) } else { - scriptArgs, err = arguments.ParseWithoutType(args[1:], code, filename) + cadenceArgs, err = arguments.ParseWithoutType(argsArr, code, location) } if err != nil { @@ -89,8 +98,8 @@ func execute( context.Background(), flowkit.Script{ Code: code, - Args: scriptArgs, - Location: filename, + Args: cadenceArgs, + Location: location, }, query, ) @@ -100,3 +109,78 @@ func execute( return &scriptResult{value}, nil } + +func executeLocalScript(args []string, filename string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { + code, err := readerWriter.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("error loading script file: %w", err) + } + + return sendScript(code, args[1:], filename, flow) +} + +func executeFlixScript(args []string, action string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { + commandParts := strings.Split(action, ":") + + if len(commandParts) != 3 { + return nil, fmt.Errorf("invalid flix command") + } + + flixFindMethod := commandParts[1] + flixIdentifier := commandParts[2] + + var parsedFlixTemplate *flixkit.FlowInteractionTemplate + var argsArr []string + + switch flixFindMethod { + case "name": + argsArr = args[1:] + flixTemplate, err := flixkit.GetFlix("https://flix.flow.com/v1/templates", flixIdentifier) + if err != nil { + return nil, fmt.Errorf("could not find flix template") + } + parsedFlixTemplate = flixTemplate + + case "id": + argsArr = args[1:] + flixTemplate, err := flixkit.GetFlixByID("https://flix.flow.com/v1/templates", flixIdentifier) + if err != nil { + return nil, fmt.Errorf("could not find flix template") + } + parsedFlixTemplate = flixTemplate + + case "local": + if flixIdentifier == "path" { + filePath := args[1] + argsArr = args[2:] + + flixTemplate, err := readerWriter.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("error loading script file: %w", err) + } + + parsedTemplate, err := flixkit.ParseFlix(string(flixTemplate)) + if err != nil { + return nil, fmt.Errorf("error parsing script file: %w", err) + } + + parsedFlixTemplate = parsedTemplate + } else { + return nil, fmt.Errorf("invalid flix command") + } + + default: + return nil, fmt.Errorf("invalid flix command") + } + + if parsedFlixTemplate.IsTransaction() { + return nil, fmt.Errorf("invalid command for a transaction") + } + + cadenceWithImportsReplaced, err := parsedFlixTemplate.GetAndReplaceCadenceImports("testnet") + if err != nil { + return nil, fmt.Errorf("could not replace imports") + } + + return sendScript([]byte(cadenceWithImportsReplaced), argsArr, "", flow) +} From d77b75e7286a3c4cb1869193d2b10e8533c45cb2 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:50:57 -0700 Subject: [PATCH 03/30] Remove print --- internal/scripts/execute.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index a9c99f536..1a06ff949 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -63,8 +63,6 @@ func execute( ) (command.Result, error) { filenameOrAction := args[0] - fmt.Println("filename: ", filenameOrAction) - if strings.HasPrefix(filenameOrAction, "flix") { return executeFlixScript(args, filenameOrAction, readerWriter, flow) } From 1f2abb50053a1de3278d3c3bba36eab13c1ad5d7 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:33:42 -0700 Subject: [PATCH 04/30] Update flixkit to new syntax --- internal/scripts/execute.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 1a06ff949..40c2bef05 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -127,13 +127,14 @@ func executeFlixScript(args []string, action string, readerWriter flowkit.Reader flixFindMethod := commandParts[1] flixIdentifier := commandParts[2] + var flixService = flixkit.NewFlixService(&flixkit.Config{}) var parsedFlixTemplate *flixkit.FlowInteractionTemplate var argsArr []string switch flixFindMethod { case "name": argsArr = args[1:] - flixTemplate, err := flixkit.GetFlix("https://flix.flow.com/v1/templates", flixIdentifier) + flixTemplate, err := flixService.GetFlix(flixIdentifier) if err != nil { return nil, fmt.Errorf("could not find flix template") } @@ -141,7 +142,7 @@ func executeFlixScript(args []string, action string, readerWriter flowkit.Reader case "id": argsArr = args[1:] - flixTemplate, err := flixkit.GetFlixByID("https://flix.flow.com/v1/templates", flixIdentifier) + flixTemplate, err := flixService.GetFlixByID(flixIdentifier) if err != nil { return nil, fmt.Errorf("could not find flix template") } From b42895e5617e82a5d47e4e9bfe18801b8182a14c Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:25:22 -0700 Subject: [PATCH 05/30] Break out flix fetching and command parsing --- internal/scripts/execute.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 40c2bef05..08f5ccec8 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -117,11 +117,11 @@ func executeLocalScript(args []string, filename string, readerWriter flowkit.Rea return sendScript(code, args[1:], filename, flow) } -func executeFlixScript(args []string, action string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { +func getFlixCadence(args []string, action string, readerWriter flowkit.ReaderWriter) (*flixkit.FlowInteractionTemplate, []string, error) { commandParts := strings.Split(action, ":") if len(commandParts) != 3 { - return nil, fmt.Errorf("invalid flix command") + return nil, nil, fmt.Errorf("invalid flix command") } flixFindMethod := commandParts[1] @@ -136,7 +136,7 @@ func executeFlixScript(args []string, action string, readerWriter flowkit.Reader argsArr = args[1:] flixTemplate, err := flixService.GetFlix(flixIdentifier) if err != nil { - return nil, fmt.Errorf("could not find flix template") + return nil, nil, fmt.Errorf("could not find flix template") } parsedFlixTemplate = flixTemplate @@ -144,7 +144,7 @@ func executeFlixScript(args []string, action string, readerWriter flowkit.Reader argsArr = args[1:] flixTemplate, err := flixService.GetFlixByID(flixIdentifier) if err != nil { - return nil, fmt.Errorf("could not find flix template") + return nil, nil, fmt.Errorf("could not find flix template") } parsedFlixTemplate = flixTemplate @@ -155,31 +155,37 @@ func executeFlixScript(args []string, action string, readerWriter flowkit.Reader flixTemplate, err := readerWriter.ReadFile(filePath) if err != nil { - return nil, fmt.Errorf("error loading script file: %w", err) + return nil, nil, fmt.Errorf("error loading script file: %w", err) } parsedTemplate, err := flixkit.ParseFlix(string(flixTemplate)) if err != nil { - return nil, fmt.Errorf("error parsing script file: %w", err) + return nil, nil, fmt.Errorf("error parsing script file: %w", err) } parsedFlixTemplate = parsedTemplate } else { - return nil, fmt.Errorf("invalid flix command") + return nil, nil, fmt.Errorf("invalid flix command") } default: - return nil, fmt.Errorf("invalid flix command") + return nil, nil, fmt.Errorf("invalid flix command") } - if parsedFlixTemplate.IsTransaction() { + return parsedFlixTemplate, argsArr, nil +} + +func executeFlixScript(args []string, action string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { + flix, updatedArgs, err := getFlixCadence(args, action, readerWriter) + + if flix.IsTransaction() { return nil, fmt.Errorf("invalid command for a transaction") } - cadenceWithImportsReplaced, err := parsedFlixTemplate.GetAndReplaceCadenceImports("testnet") + cadenceWithImportsReplaced, err := flix.GetAndReplaceCadenceImports("testnet") if err != nil { return nil, fmt.Errorf("could not replace imports") } - return sendScript([]byte(cadenceWithImportsReplaced), argsArr, "", flow) + return sendScript([]byte(cadenceWithImportsReplaced), updatedArgs, "", flow) } From 97e556e6bbb61c81127983cf9725acf8ea64c9fb Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 18 Jul 2023 10:16:20 -0700 Subject: [PATCH 06/30] Add context --- internal/scripts/execute.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 08f5ccec8..615c35127 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -134,7 +134,8 @@ func getFlixCadence(args []string, action string, readerWriter flowkit.ReaderWri switch flixFindMethod { case "name": argsArr = args[1:] - flixTemplate, err := flixService.GetFlix(flixIdentifier) + ctx := context.Background() + flixTemplate, err := flixService.GetFlix(ctx, flixIdentifier) if err != nil { return nil, nil, fmt.Errorf("could not find flix template") } @@ -142,7 +143,8 @@ func getFlixCadence(args []string, action string, readerWriter flowkit.ReaderWri case "id": argsArr = args[1:] - flixTemplate, err := flixService.GetFlixByID(flixIdentifier) + ctx := context.Background() + flixTemplate, err := flixService.GetFlixByID(ctx, flixIdentifier) if err != nil { return nil, nil, fmt.Errorf("could not find flix template") } From 42e29e003e8d019b2c5fcd3d6c8277bc94521b76 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 18 Jul 2023 11:08:01 -0700 Subject: [PATCH 07/30] Rename for clarity --- internal/scripts/execute.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 615c35127..489830575 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -117,7 +117,7 @@ func executeLocalScript(args []string, filename string, readerWriter flowkit.Rea return sendScript(code, args[1:], filename, flow) } -func getFlixCadence(args []string, action string, readerWriter flowkit.ReaderWriter) (*flixkit.FlowInteractionTemplate, []string, error) { +func getFlix(args []string, action string, readerWriter flowkit.ReaderWriter) (*flixkit.FlowInteractionTemplate, []string, error) { commandParts := strings.Split(action, ":") if len(commandParts) != 3 { @@ -128,44 +128,44 @@ func getFlixCadence(args []string, action string, readerWriter flowkit.ReaderWri flixIdentifier := commandParts[2] var flixService = flixkit.NewFlixService(&flixkit.Config{}) - var parsedFlixTemplate *flixkit.FlowInteractionTemplate - var argsArr []string + var template *flixkit.FlowInteractionTemplate + var flixArgs []string switch flixFindMethod { case "name": - argsArr = args[1:] + flixArgs = args[1:] ctx := context.Background() - flixTemplate, err := flixService.GetFlix(ctx, flixIdentifier) + flixRes, err := flixService.GetFlix(ctx, flixIdentifier) if err != nil { return nil, nil, fmt.Errorf("could not find flix template") } - parsedFlixTemplate = flixTemplate + template = flixRes case "id": - argsArr = args[1:] + flixArgs = args[1:] ctx := context.Background() - flixTemplate, err := flixService.GetFlixByID(ctx, flixIdentifier) + flixRes, err := flixService.GetFlixByID(ctx, flixIdentifier) if err != nil { return nil, nil, fmt.Errorf("could not find flix template") } - parsedFlixTemplate = flixTemplate + template = flixRes case "local": if flixIdentifier == "path" { filePath := args[1] - argsArr = args[2:] + flixArgs = args[2:] - flixTemplate, err := readerWriter.ReadFile(filePath) + flixFile, err := readerWriter.ReadFile(filePath) if err != nil { return nil, nil, fmt.Errorf("error loading script file: %w", err) } - parsedTemplate, err := flixkit.ParseFlix(string(flixTemplate)) + flixRes, err := flixkit.ParseFlix(string(flixFile)) if err != nil { return nil, nil, fmt.Errorf("error parsing script file: %w", err) } - parsedFlixTemplate = parsedTemplate + template = flixRes } else { return nil, nil, fmt.Errorf("invalid flix command") } @@ -174,11 +174,11 @@ func getFlixCadence(args []string, action string, readerWriter flowkit.ReaderWri return nil, nil, fmt.Errorf("invalid flix command") } - return parsedFlixTemplate, argsArr, nil + return template, flixArgs, nil } func executeFlixScript(args []string, action string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { - flix, updatedArgs, err := getFlixCadence(args, action, readerWriter) + flix, updatedArgs, err := getFlix(args, action, readerWriter) if flix.IsTransaction() { return nil, fmt.Errorf("invalid command for a transaction") From 70c208d23bc54930dad483611343d7a1a832a18a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:03:23 -0700 Subject: [PATCH 08/30] Send flix transactions --- internal/flix/flix.go | 70 +++++++++++++++++++++++++++++++++ internal/scripts/execute.go | 73 +++-------------------------------- internal/transactions/send.go | 50 ++++++++++++++++++++---- 3 files changed, 118 insertions(+), 75 deletions(-) create mode 100644 internal/flix/flix.go diff --git a/internal/flix/flix.go b/internal/flix/flix.go new file mode 100644 index 000000000..df12349e7 --- /dev/null +++ b/internal/flix/flix.go @@ -0,0 +1,70 @@ +package flix + +import ( + "context" + "fmt" + "strings" + + "github.com/onflow/flixkit-go" + "github.com/onflow/flow-cli/flowkit" +) + +func GetFlix(args []string, action string, readerWriter flowkit.ReaderWriter) (*flixkit.FlowInteractionTemplate, []string, error) { + commandParts := strings.Split(action, ":") + + if len(commandParts) != 3 { + return nil, nil, fmt.Errorf("invalid flix command") + } + + flixFindMethod := commandParts[1] + flixIdentifier := commandParts[2] + + var flixService = flixkit.NewFlixService(&flixkit.Config{}) + var template *flixkit.FlowInteractionTemplate + var argsArr []string + + switch flixFindMethod { + case "name": + argsArr = args[1:] + ctx := context.Background() + flixRes, err := flixService.GetFlix(ctx, flixIdentifier) + if err != nil { + return nil, nil, fmt.Errorf("could not find flix template") + } + template = flixRes + + case "id": + argsArr = args[1:] + ctx := context.Background() + flixRes, err := flixService.GetFlixByID(ctx, flixIdentifier) + if err != nil { + return nil, nil, fmt.Errorf("could not find flix template") + } + template = flixRes + + case "local": + if flixIdentifier == "path" { + filePath := args[1] + argsArr = args[2:] + + flixFile, err := readerWriter.ReadFile(filePath) + if err != nil { + return nil, nil, fmt.Errorf("error loading script file: %w", err) + } + + flixRes, err := flixkit.ParseFlix(string(flixFile)) + if err != nil { + return nil, nil, fmt.Errorf("error parsing script file: %w", err) + } + + template = flixRes + } else { + return nil, nil, fmt.Errorf("invalid flix command") + } + + default: + return nil, nil, fmt.Errorf("invalid flix command") + } + + return template, argsArr, nil +} diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 489830575..0986c0b51 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -23,8 +23,6 @@ import ( "fmt" "strings" - "github.com/onflow/flixkit-go" - "github.com/onflow/cadence" flowsdk "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" @@ -33,6 +31,7 @@ import ( "github.com/onflow/flow-cli/flowkit/arguments" "github.com/onflow/flow-cli/flowkit/output" "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/internal/flix" ) type flagsScripts struct { @@ -117,77 +116,17 @@ func executeLocalScript(args []string, filename string, readerWriter flowkit.Rea return sendScript(code, args[1:], filename, flow) } -func getFlix(args []string, action string, readerWriter flowkit.ReaderWriter) (*flixkit.FlowInteractionTemplate, []string, error) { - commandParts := strings.Split(action, ":") - - if len(commandParts) != 3 { - return nil, nil, fmt.Errorf("invalid flix command") - } - - flixFindMethod := commandParts[1] - flixIdentifier := commandParts[2] - - var flixService = flixkit.NewFlixService(&flixkit.Config{}) - var template *flixkit.FlowInteractionTemplate - var flixArgs []string - - switch flixFindMethod { - case "name": - flixArgs = args[1:] - ctx := context.Background() - flixRes, err := flixService.GetFlix(ctx, flixIdentifier) - if err != nil { - return nil, nil, fmt.Errorf("could not find flix template") - } - template = flixRes - - case "id": - flixArgs = args[1:] - ctx := context.Background() - flixRes, err := flixService.GetFlixByID(ctx, flixIdentifier) - if err != nil { - return nil, nil, fmt.Errorf("could not find flix template") - } - template = flixRes - - case "local": - if flixIdentifier == "path" { - filePath := args[1] - flixArgs = args[2:] - - flixFile, err := readerWriter.ReadFile(filePath) - if err != nil { - return nil, nil, fmt.Errorf("error loading script file: %w", err) - } - - flixRes, err := flixkit.ParseFlix(string(flixFile)) - if err != nil { - return nil, nil, fmt.Errorf("error parsing script file: %w", err) - } - - template = flixRes - } else { - return nil, nil, fmt.Errorf("invalid flix command") - } - - default: - return nil, nil, fmt.Errorf("invalid flix command") - } - - return template, flixArgs, nil -} - func executeFlixScript(args []string, action string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { - flix, updatedArgs, err := getFlix(args, action, readerWriter) + template, flixArgs, err := flix.GetFlix(args, action, readerWriter) - if flix.IsTransaction() { - return nil, fmt.Errorf("invalid command for a transaction") + if template.IsTransaction() { + return nil, fmt.Errorf("invalid template for command") } - cadenceWithImportsReplaced, err := flix.GetAndReplaceCadenceImports("testnet") + cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports("testnet") if err != nil { return nil, fmt.Errorf("could not replace imports") } - return sendScript([]byte(cadenceWithImportsReplaced), updatedArgs, "", flow) + return sendScript([]byte(cadenceWithImportsReplaced), flixArgs, "", flow) } diff --git a/internal/transactions/send.go b/internal/transactions/send.go index 78f036fc1..00b50a930 100644 --- a/internal/transactions/send.go +++ b/internal/transactions/send.go @@ -21,6 +21,9 @@ package transactions import ( "context" "fmt" + "strings" + + "github.com/onflow/flow-cli/internal/flix" "github.com/onflow/cadence" "github.com/spf13/cobra" @@ -64,8 +67,43 @@ func send( flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - codeFilename := args[0] + filenameOrAction := args[0] + + if strings.HasPrefix(filenameOrAction, "flix") { + return executeFlixTransaction(args, filenameOrAction, flow, state) + } + + return executeLocalTransaction(args, filenameOrAction, flow, state) +} + +func executeLocalTransaction(args []string, filename string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { + code, err := state.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("error loading transaction file: %w", err) + } + + return sendTransaction(code, args, filename, flow, state) +} + +func executeFlixTransaction(args []string, action string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { + template, flixArgs, err := flix.GetFlix(args, action, state.ReaderWriter()) + if err != nil { + return nil, err + } + + if template.IsScript() { + return nil, fmt.Errorf("invalid template for command") + } + + cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports("testnet") + if err != nil { + return nil, fmt.Errorf("could not replace imports") + } + return sendTransaction([]byte(cadenceWithImportsReplaced), flixArgs, "", flow, state) +} + +func sendTransaction(code []byte, args []string, location string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { proposerName := sendFlags.Proposer var proposer *accounts.Account if proposerName != "" { @@ -112,16 +150,12 @@ func send( authorizers = append(authorizers, *signer) } - code, err := state.ReadFile(codeFilename) - if err != nil { - return nil, fmt.Errorf("error loading transaction file: %w", err) - } - var transactionArgs []cadence.Value if sendFlags.ArgsJSON != "" { transactionArgs, err = arguments.ParseJSON(sendFlags.ArgsJSON) } else { - transactionArgs, err = arguments.ParseWithoutType(args[1:], code, codeFilename) + fmt.Println("args: ", args) + transactionArgs, err = arguments.ParseWithoutType(args, code, location) } if err != nil { return nil, fmt.Errorf("error parsing transaction arguments: %w", err) @@ -134,7 +168,7 @@ func send( Authorizers: authorizers, Payer: *payer, }, - flowkit.Script{Code: code, Args: transactionArgs, Location: codeFilename}, + flowkit.Script{Code: code, Args: transactionArgs, Location: location}, sendFlags.GasLimit, ) From 0c763575e7c405870630ac0ae62fb21e5248fb1a Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:04:32 -0700 Subject: [PATCH 09/30] Remove print --- internal/transactions/send.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/transactions/send.go b/internal/transactions/send.go index 00b50a930..1807d577d 100644 --- a/internal/transactions/send.go +++ b/internal/transactions/send.go @@ -154,7 +154,6 @@ func sendTransaction(code []byte, args []string, location string, flow flowkit.S if sendFlags.ArgsJSON != "" { transactionArgs, err = arguments.ParseJSON(sendFlags.ArgsJSON) } else { - fmt.Println("args: ", args) transactionArgs, err = arguments.ParseWithoutType(args, code, location) } if err != nil { From 9806fcd7b0b39af214ba276919b006cc54169c03 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:52:03 -0700 Subject: [PATCH 10/30] Move to flix commands --- cmd/flow/main.go | 2 + internal/flix/flix.go | 150 ++++++++++++++++++++++++---------- internal/scripts/execute.go | 29 +------ internal/transactions/send.go | 33 +------- 4 files changed, 116 insertions(+), 98 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 85f0b23a7..31a011b37 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -32,6 +32,7 @@ import ( "github.com/onflow/flow-cli/internal/config" "github.com/onflow/flow-cli/internal/emulator" "github.com/onflow/flow-cli/internal/events" + "github.com/onflow/flow-cli/internal/flix" "github.com/onflow/flow-cli/internal/keys" "github.com/onflow/flow-cli/internal/project" "github.com/onflow/flow-cli/internal/quick" @@ -85,6 +86,7 @@ func main() { cmd.AddCommand(config.Cmd) cmd.AddCommand(signatures.Cmd) cmd.AddCommand(snapshot.Cmd) + cmd.AddCommand(flix.Cmd) command.InitFlags(cmd) cmd.AddGroup(&cobra.Group{ diff --git a/internal/flix/flix.go b/internal/flix/flix.go index df12349e7..c1f5c5afc 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -3,68 +3,134 @@ package flix import ( "context" "fmt" - "strings" + "os" + + "github.com/onflow/flow-cli/internal/scripts" + + "github.com/onflow/flow-cli/internal/transactions" "github.com/onflow/flixkit-go" "github.com/onflow/flow-cli/flowkit" + "github.com/onflow/flow-cli/flowkit/output" + "github.com/onflow/flow-cli/internal/command" + "github.com/spf13/cobra" ) -func GetFlix(args []string, action string, readerWriter flowkit.ReaderWriter) (*flixkit.FlowInteractionTemplate, []string, error) { - commandParts := strings.Split(action, ":") - - if len(commandParts) != 3 { - return nil, nil, fmt.Errorf("invalid flix command") - } +type flagsOpts struct { + ArgsJSON string `default:"" flag:"args-json" info:"arguments in JSON-Cadence format"` + BlockID string `default:"" flag:"block-id" info:"block ID to execute the script at"` + BlockHeight uint64 `default:"" flag:"block-height" info:"block height to execute the script at"` + Signer string `default:"" flag:"signer" info:"Account name from configuration used to sign the transaction as proposer, payer and suthorizer"` + Proposer string `default:"" flag:"proposer" info:"Account name from configuration used as proposer"` + Payer string `default:"" flag:"payer" info:"Account name from configuration used as payer"` + Authorizers []string `default:"" flag:"authorizer" info:"Name of a single or multiple comma-separated accounts used as authorizers from configuration"` + Include []string `default:"" flag:"include" info:"Fields to include in the output"` + Exclude []string `default:"" flag:"exclude" info:"Fields to exclude from the output (events)"` + GasLimit uint64 `default:"1000" flag:"gas-limit" info:"transaction gas limit"` +} - flixFindMethod := commandParts[1] - flixIdentifier := commandParts[2] +var flags = flagsOpts{} - var flixService = flixkit.NewFlixService(&flixkit.Config{}) - var template *flixkit.FlowInteractionTemplate - var argsArr []string +var Cmd = &cobra.Command{ + Use: "flix", + Short: "Commands for the Flix functionality", +} - switch flixFindMethod { - case "name": - argsArr = args[1:] +var idCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "id ", + Short: "Execute flix operation with given id", + Args: cobra.MinimumNArgs(1), + Example: `flow flix id 123`, + }, + Flags: &flags, + RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { + flixService := flixkit.NewFlixService(&flixkit.Config{}) + flixID := args[0] ctx := context.Background() - flixRes, err := flixService.GetFlix(ctx, flixIdentifier) + template, err := flixService.GetFlixByID(ctx, flixID) if err != nil { - return nil, nil, fmt.Errorf("could not find flix template") + return nil, fmt.Errorf("could not find flix template") } - template = flixRes - case "id": - argsArr = args[1:] - ctx := context.Background() - flixRes, err := flixService.GetFlixByID(ctx, flixIdentifier) + cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) if err != nil { - return nil, nil, fmt.Errorf("could not find flix template") + return nil, fmt.Errorf("could not replace imports") } - template = flixRes - case "local": - if flixIdentifier == "path" { - filePath := args[1] - argsArr = args[2:] + if template.IsScript() { + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow) + } else { + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state) + } + }, +} - flixFile, err := readerWriter.ReadFile(filePath) - if err != nil { - return nil, nil, fmt.Errorf("error loading script file: %w", err) - } +var nameCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "name ", + Short: "Execute flix operation with given name", + Args: cobra.MinimumNArgs(1), + Example: `flow flix name transfer-flow`, + }, + Flags: &flags, + RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { + flixService := flixkit.NewFlixService(&flixkit.Config{}) + flixName := args[0] + ctx := context.Background() + template, err := flixService.GetFlix(ctx, flixName) + if err != nil { + return nil, fmt.Errorf("could not find flix template") + } - flixRes, err := flixkit.ParseFlix(string(flixFile)) - if err != nil { - return nil, nil, fmt.Errorf("error parsing script file: %w", err) - } + cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) + if err != nil { + return nil, fmt.Errorf("could not replace imports") + } - template = flixRes + if template.IsScript() { + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow) } else { - return nil, nil, fmt.Errorf("invalid flix command") + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state) + } + }, +} + +var pathCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "path ", + Short: "Execute flix operation with given name", + Args: cobra.MinimumNArgs(1), + Example: `flow flix path transfer-flow`, + }, + Flags: &flags, + RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { + filePath := args[0] + file, err := os.ReadFile(filePath) + if err != nil { + return nil, fmt.Errorf("could not read file") + } + + template, err := flixkit.ParseFlix(string(file)) + if err != nil { + return nil, fmt.Errorf("could not parse flix") } - default: - return nil, nil, fmt.Errorf("invalid flix command") - } + cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) + if err != nil { + return nil, fmt.Errorf("could not replace imports") + } + + if template.IsScript() { + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow) + } else { + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state) + } + }, +} - return template, argsArr, nil +func init() { + idCommand.AddToParent(Cmd) + nameCommand.AddToParent(Cmd) + pathCommand.AddToParent(Cmd) } diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 0986c0b51..16f77359f 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -21,7 +21,6 @@ package scripts import ( "context" "fmt" - "strings" "github.com/onflow/cadence" flowsdk "github.com/onflow/flow-go-sdk" @@ -31,7 +30,6 @@ import ( "github.com/onflow/flow-cli/flowkit/arguments" "github.com/onflow/flow-cli/flowkit/output" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/flix" ) type flagsScripts struct { @@ -60,16 +58,10 @@ func execute( readerWriter flowkit.ReaderWriter, flow flowkit.Services, ) (command.Result, error) { - filenameOrAction := args[0] - - if strings.HasPrefix(filenameOrAction, "flix") { - return executeFlixScript(args, filenameOrAction, readerWriter, flow) - } - - return executeLocalScript(args, filenameOrAction, readerWriter, flow) + return executeLocalScript(args, args[0], readerWriter, flow) } -func sendScript(code []byte, argsArr []string, location string, flow flowkit.Services) (command.Result, error) { +func SendScript(code []byte, argsArr []string, location string, flow flowkit.Services) (command.Result, error) { var cadenceArgs []cadence.Value var err error if scriptFlags.ArgsJSON != "" { @@ -113,20 +105,5 @@ func executeLocalScript(args []string, filename string, readerWriter flowkit.Rea return nil, fmt.Errorf("error loading script file: %w", err) } - return sendScript(code, args[1:], filename, flow) -} - -func executeFlixScript(args []string, action string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { - template, flixArgs, err := flix.GetFlix(args, action, readerWriter) - - if template.IsTransaction() { - return nil, fmt.Errorf("invalid template for command") - } - - cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports("testnet") - if err != nil { - return nil, fmt.Errorf("could not replace imports") - } - - return sendScript([]byte(cadenceWithImportsReplaced), flixArgs, "", flow) + return SendScript(code, args[1:], filename, flow) } diff --git a/internal/transactions/send.go b/internal/transactions/send.go index 1807d577d..8443c08ce 100644 --- a/internal/transactions/send.go +++ b/internal/transactions/send.go @@ -21,9 +21,6 @@ package transactions import ( "context" "fmt" - "strings" - - "github.com/onflow/flow-cli/internal/flix" "github.com/onflow/cadence" "github.com/spf13/cobra" @@ -67,13 +64,7 @@ func send( flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - filenameOrAction := args[0] - - if strings.HasPrefix(filenameOrAction, "flix") { - return executeFlixTransaction(args, filenameOrAction, flow, state) - } - - return executeLocalTransaction(args, filenameOrAction, flow, state) + return executeLocalTransaction(args, args[0], flow, state) } func executeLocalTransaction(args []string, filename string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { @@ -82,28 +73,10 @@ func executeLocalTransaction(args []string, filename string, flow flowkit.Servic return nil, fmt.Errorf("error loading transaction file: %w", err) } - return sendTransaction(code, args, filename, flow, state) -} - -func executeFlixTransaction(args []string, action string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { - template, flixArgs, err := flix.GetFlix(args, action, state.ReaderWriter()) - if err != nil { - return nil, err - } - - if template.IsScript() { - return nil, fmt.Errorf("invalid template for command") - } - - cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports("testnet") - if err != nil { - return nil, fmt.Errorf("could not replace imports") - } - - return sendTransaction([]byte(cadenceWithImportsReplaced), flixArgs, "", flow, state) + return SendTransaction(code, args, filename, flow, state) } -func sendTransaction(code []byte, args []string, location string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { +func SendTransaction(code []byte, args []string, location string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { proposerName := sendFlags.Proposer var proposer *accounts.Account if proposerName != "" { From 4fe6c4142d9de189f5bd259e5d83dea2d06aa080 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 1 Aug 2023 15:59:48 -0700 Subject: [PATCH 11/30] Change flix syntax and use cobra --- internal/flix/flix.go | 61 ++++++++++++++++++++++++++++++----- internal/scripts/execute.go | 10 +++--- internal/transactions/send.go | 10 +++--- 3 files changed, 63 insertions(+), 18 deletions(-) diff --git a/internal/flix/flix.go b/internal/flix/flix.go index c1f5c5afc..a3fa4478a 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -16,7 +16,7 @@ import ( "github.com/spf13/cobra" ) -type flagsOpts struct { +type Flags struct { ArgsJSON string `default:"" flag:"args-json" info:"arguments in JSON-Cadence format"` BlockID string `default:"" flag:"block-id" info:"block ID to execute the script at"` BlockHeight uint64 `default:"" flag:"block-height" info:"block height to execute the script at"` @@ -29,7 +29,7 @@ type flagsOpts struct { GasLimit uint64 `default:"1000" flag:"gas-limit" info:"transaction gas limit"` } -var flags = flagsOpts{} +var flags = Flags{} var Cmd = &cobra.Command{ Use: "flix", @@ -59,9 +59,24 @@ var idCommand = &command.Command{ } if template.IsScript() { - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow) + scriptsFlags := scripts.Flags{ + ArgsJSON: flags.ArgsJSON, + BlockID: flags.BlockID, + BlockHeight: flags.BlockHeight, + } + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) } else { - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state) + transactionFlags := transactions.Flags{ + ArgsJSON: flags.ArgsJSON, + Signer: flags.Signer, + Proposer: flags.Proposer, + Payer: flags.Payer, + Authorizers: flags.Authorizers, + Include: flags.Include, + Exclude: flags.Exclude, + GasLimit: flags.GasLimit, + } + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) } }, } @@ -89,9 +104,24 @@ var nameCommand = &command.Command{ } if template.IsScript() { - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow) + scriptsFlags := scripts.Flags{ + ArgsJSON: flags.ArgsJSON, + BlockID: flags.BlockID, + BlockHeight: flags.BlockHeight, + } + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) } else { - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state) + transactionFlags := transactions.Flags{ + ArgsJSON: flags.ArgsJSON, + Signer: flags.Signer, + Proposer: flags.Proposer, + Payer: flags.Payer, + Authorizers: flags.Authorizers, + Include: flags.Include, + Exclude: flags.Exclude, + GasLimit: flags.GasLimit, + } + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) } }, } @@ -122,9 +152,24 @@ var pathCommand = &command.Command{ } if template.IsScript() { - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow) + scriptsFlags := scripts.Flags{ + ArgsJSON: flags.ArgsJSON, + BlockID: flags.BlockID, + BlockHeight: flags.BlockHeight, + } + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) } else { - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state) + transactionFlags := transactions.Flags{ + ArgsJSON: flags.ArgsJSON, + Signer: flags.Signer, + Proposer: flags.Proposer, + Payer: flags.Payer, + Authorizers: flags.Authorizers, + Include: flags.Include, + Exclude: flags.Exclude, + GasLimit: flags.GasLimit, + } + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) } }, } diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 16f77359f..19def616b 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -32,13 +32,13 @@ import ( "github.com/onflow/flow-cli/internal/command" ) -type flagsScripts struct { +type Flags struct { ArgsJSON string `default:"" flag:"args-json" info:"arguments in JSON-Cadence format"` BlockID string `default:"" flag:"block-id" info:"block ID to execute the script at"` BlockHeight uint64 `default:"" flag:"block-height" info:"block height to execute the script at"` } -var scriptFlags = flagsScripts{} +var flags = Flags{} var executeCommand = &command.Command{ Cmd: &cobra.Command{ @@ -47,7 +47,7 @@ var executeCommand = &command.Command{ Example: `flow scripts execute script.cdc "Meow" "Woof"`, Args: cobra.MinimumNArgs(1), }, - Flags: &scriptFlags, + Flags: &flags, Run: execute, } @@ -61,7 +61,7 @@ func execute( return executeLocalScript(args, args[0], readerWriter, flow) } -func SendScript(code []byte, argsArr []string, location string, flow flowkit.Services) (command.Result, error) { +func SendScript(code []byte, argsArr []string, location string, flow flowkit.Services, scriptFlags Flags) (command.Result, error) { var cadenceArgs []cadence.Value var err error if scriptFlags.ArgsJSON != "" { @@ -105,5 +105,5 @@ func executeLocalScript(args []string, filename string, readerWriter flowkit.Rea return nil, fmt.Errorf("error loading script file: %w", err) } - return SendScript(code, args[1:], filename, flow) + return SendScript(code, args[1:], filename, flow, flags) } diff --git a/internal/transactions/send.go b/internal/transactions/send.go index 8443c08ce..9b11d5e2c 100644 --- a/internal/transactions/send.go +++ b/internal/transactions/send.go @@ -33,7 +33,7 @@ import ( "github.com/onflow/flow-cli/internal/command" ) -type flagsSend struct { +type Flags struct { ArgsJSON string `default:"" flag:"args-json" info:"arguments in JSON-Cadence format"` Signer string `default:"" flag:"signer" info:"Account name from configuration used to sign the transaction as proposer, payer and suthorizer"` Proposer string `default:"" flag:"proposer" info:"Account name from configuration used as proposer"` @@ -44,7 +44,7 @@ type flagsSend struct { GasLimit uint64 `default:"1000" flag:"gas-limit" info:"transaction gas limit"` } -var sendFlags = flagsSend{} +var flags = Flags{} var sendCommand = &command.Command{ Cmd: &cobra.Command{ @@ -53,7 +53,7 @@ var sendCommand = &command.Command{ Args: cobra.MinimumNArgs(1), Example: `flow transactions send tx.cdc "Hello world"`, }, - Flags: &sendFlags, + Flags: &flags, RunS: send, } @@ -73,10 +73,10 @@ func executeLocalTransaction(args []string, filename string, flow flowkit.Servic return nil, fmt.Errorf("error loading transaction file: %w", err) } - return SendTransaction(code, args, filename, flow, state) + return SendTransaction(code, args, filename, flow, state, flags) } -func SendTransaction(code []byte, args []string, location string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { +func SendTransaction(code []byte, args []string, location string, flow flowkit.Services, state *flowkit.State, sendFlags Flags) (result command.Result, err error) { proposerName := sendFlags.Proposer var proposer *accounts.Account if proposerName != "" { From 906845d6976b059a74de1a30612879cd91724238 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Tue, 1 Aug 2023 16:16:15 -0700 Subject: [PATCH 12/30] Fix tests --- internal/scripts/scripts_test.go | 2 +- internal/transactions/transactions_test.go | 26 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/internal/scripts/scripts_test.go b/internal/scripts/scripts_test.go index 22706228b..baa191f3d 100644 --- a/internal/scripts/scripts_test.go +++ b/internal/scripts/scripts_test.go @@ -58,7 +58,7 @@ func Test_Execute(t *testing.T) { t.Run("Fail parsing invalid JSON args", func(t *testing.T) { inArgs := []string{tests.TestScriptSimple.Filename} - scriptFlags.ArgsJSON = "invalid" + flags.ArgsJSON = "invalid" result, err := execute(inArgs, command.GlobalFlags{}, util.NoLogger, rw, srv.Mock) assert.Nil(t, result) diff --git a/internal/transactions/transactions_test.go b/internal/transactions/transactions_test.go index 84f5900c0..5d41f0e46 100644 --- a/internal/transactions/transactions_test.go +++ b/internal/transactions/transactions_test.go @@ -140,8 +140,8 @@ func Test_Send(t *testing.T) { t.Run("Success", func(t *testing.T) { const gas = uint64(1000) - sendFlags.GasLimit = gas - inArgs := []string{tests.TransactionArgString.Filename, "foo"} + flags.GasLimit = gas + inArgs := []string{tests.TransactionArgString.Filename} srv.SendTransaction.Run(func(args mock.Arguments) { roles := args.Get(1).(transactions.AccountRoles) @@ -160,33 +160,33 @@ func Test_Send(t *testing.T) { }) t.Run("Fail non-existing account", func(t *testing.T) { - sendFlags.Proposer = "invalid" + flags.Proposer = "invalid" _, err := send([]string{""}, command.GlobalFlags{}, util.NoLogger, srv.Mock, state) assert.EqualError(t, err, "proposer account: [invalid] doesn't exists in configuration") - sendFlags.Proposer = "" // reset + flags.Proposer = "" // reset - sendFlags.Payer = "invalid" + flags.Payer = "invalid" _, err = send([]string{""}, command.GlobalFlags{}, util.NoLogger, srv.Mock, state) assert.EqualError(t, err, "payer account: [invalid] doesn't exists in configuration") - sendFlags.Payer = "" // reset + flags.Payer = "" // reset - sendFlags.Authorizers = []string{"invalid"} + flags.Authorizers = []string{"invalid"} _, err = send([]string{""}, command.GlobalFlags{}, util.NoLogger, srv.Mock, state) assert.EqualError(t, err, "authorizer account: [invalid] doesn't exists in configuration") - sendFlags.Authorizers = nil // reset + flags.Authorizers = nil // reset - sendFlags.Signer = "invalid" + flags.Signer = "invalid" _, err = send([]string{""}, command.GlobalFlags{}, util.NoLogger, srv.Mock, state) assert.EqualError(t, err, "signer account: [invalid] doesn't exists in configuration") - sendFlags.Signer = "" // reset + flags.Signer = "" // reset }) t.Run("Fail signer and payer flag", func(t *testing.T) { - sendFlags.Proposer = config.DefaultEmulator.ServiceAccount - sendFlags.Signer = config.DefaultEmulator.ServiceAccount + flags.Proposer = config.DefaultEmulator.ServiceAccount + flags.Signer = config.DefaultEmulator.ServiceAccount _, err := send([]string{""}, command.GlobalFlags{}, util.NoLogger, srv.Mock, state) assert.EqualError(t, err, "signer flag cannot be combined with payer/proposer/authorizer flags") - sendFlags.Signer = "" // reset + flags.Signer = "" // reset }) t.Run("Fail loading transaction file", func(t *testing.T) { From d4182a2e7a1d80fa56a6bc34ce3c87c944abaf30 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 2 Aug 2023 11:22:42 -0700 Subject: [PATCH 13/30] Consolidate with flags approach --- cmd/flow/main.go | 5 +- internal/flix/flix.go | 146 +++++++++--------------------------------- 2 files changed, 35 insertions(+), 116 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 31a011b37..fdf370bd5 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -22,6 +22,8 @@ package main import ( "os" + "github.com/onflow/flow-cli/internal/flix" + "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/accounts" @@ -32,7 +34,6 @@ import ( "github.com/onflow/flow-cli/internal/config" "github.com/onflow/flow-cli/internal/emulator" "github.com/onflow/flow-cli/internal/events" - "github.com/onflow/flow-cli/internal/flix" "github.com/onflow/flow-cli/internal/keys" "github.com/onflow/flow-cli/internal/project" "github.com/onflow/flow-cli/internal/quick" @@ -86,7 +87,7 @@ func main() { cmd.AddCommand(config.Cmd) cmd.AddCommand(signatures.Cmd) cmd.AddCommand(snapshot.Cmd) - cmd.AddCommand(flix.Cmd) + cmd.AddCommand(flix.FlixCommand.Cmd) command.InitFlags(cmd) cmd.AddGroup(&cobra.Group{ diff --git a/internal/flix/flix.go b/internal/flix/flix.go index a3fa4478a..2053c09a1 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -5,18 +5,19 @@ import ( "fmt" "os" - "github.com/onflow/flow-cli/internal/scripts" + "github.com/onflow/flow-cli/flowkit/output" + "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/internal/transactions" + "github.com/onflow/flow-cli/flowkit" "github.com/onflow/flixkit-go" - "github.com/onflow/flow-cli/flowkit" - "github.com/onflow/flow-cli/flowkit/output" - "github.com/onflow/flow-cli/internal/command" + + "github.com/onflow/flow-cli/internal/scripts" + "github.com/onflow/flow-cli/internal/transactions" "github.com/spf13/cobra" ) -type Flags struct { +type flixFlags struct { ArgsJSON string `default:"" flag:"args-json" info:"arguments in JSON-Cadence format"` BlockID string `default:"" flag:"block-id" info:"block ID to execute the script at"` BlockHeight uint64 `default:"" flag:"block-height" info:"block height to execute the script at"` @@ -27,123 +28,46 @@ type Flags struct { Include []string `default:"" flag:"include" info:"Fields to include in the output"` Exclude []string `default:"" flag:"exclude" info:"Fields to exclude from the output (events)"` GasLimit uint64 `default:"1000" flag:"gas-limit" info:"transaction gas limit"` + ID string `default:"" flag:"id" info:"id of the flix"` + Name string `default:"" flag:"name" info:"name of the flix"` + Path string `default:"" flag:"path" info:"path to the flix file"` } -var flags = Flags{} +var flags = flixFlags{} -var Cmd = &cobra.Command{ - Use: "flix", - Short: "Commands for the Flix functionality", -} - -var idCommand = &command.Command{ +var FlixCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "id ", - Short: "Execute flix operation with given id", + Use: "flix [ ...]", + Short: "Execute flix operation with given id, name or path", Args: cobra.MinimumNArgs(1), - Example: `flow flix id 123`, + Example: `flow flix --id 123`, }, Flags: &flags, RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { flixService := flixkit.NewFlixService(&flixkit.Config{}) - flixID := args[0] ctx := context.Background() - template, err := flixService.GetFlixByID(ctx, flixID) - if err != nil { - return nil, fmt.Errorf("could not find flix template") - } - - cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) - if err != nil { - return nil, fmt.Errorf("could not replace imports") - } + var template *flixkit.FlowInteractionTemplate - if template.IsScript() { - scriptsFlags := scripts.Flags{ - ArgsJSON: flags.ArgsJSON, - BlockID: flags.BlockID, - BlockHeight: flags.BlockHeight, - } - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) - } else { - transactionFlags := transactions.Flags{ - ArgsJSON: flags.ArgsJSON, - Signer: flags.Signer, - Proposer: flags.Proposer, - Payer: flags.Payer, - Authorizers: flags.Authorizers, - Include: flags.Include, - Exclude: flags.Exclude, - GasLimit: flags.GasLimit, + if flags.ID != "" { + template, err = flixService.GetFlixByID(ctx, flags.ID) + if err != nil { + return nil, fmt.Errorf("could not find flix with id %s", flags.ID) } - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) - } - }, -} - -var nameCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "name ", - Short: "Execute flix operation with given name", - Args: cobra.MinimumNArgs(1), - Example: `flow flix name transfer-flow`, - }, - Flags: &flags, - RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { - flixService := flixkit.NewFlixService(&flixkit.Config{}) - flixName := args[0] - ctx := context.Background() - template, err := flixService.GetFlix(ctx, flixName) - if err != nil { - return nil, fmt.Errorf("could not find flix template") - } - - cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) - if err != nil { - return nil, fmt.Errorf("could not replace imports") - } - - if template.IsScript() { - scriptsFlags := scripts.Flags{ - ArgsJSON: flags.ArgsJSON, - BlockID: flags.BlockID, - BlockHeight: flags.BlockHeight, + } else if flags.Name != "" { + template, err = flixService.GetFlix(ctx, flags.Name) + if err != nil { + return nil, fmt.Errorf("could not find flix with name %s", flags.Name) } - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) - } else { - transactionFlags := transactions.Flags{ - ArgsJSON: flags.ArgsJSON, - Signer: flags.Signer, - Proposer: flags.Proposer, - Payer: flags.Payer, - Authorizers: flags.Authorizers, - Include: flags.Include, - Exclude: flags.Exclude, - GasLimit: flags.GasLimit, + } else if flags.Path != "" { + file, err := os.ReadFile(flags.Path) + if err != nil { + return nil, fmt.Errorf("could not read file") } - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) - } - }, -} - -var pathCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "path ", - Short: "Execute flix operation with given name", - Args: cobra.MinimumNArgs(1), - Example: `flow flix path transfer-flow`, - }, - Flags: &flags, - RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { - filePath := args[0] - file, err := os.ReadFile(filePath) - if err != nil { - return nil, fmt.Errorf("could not read file") + template, err = flixkit.ParseFlix(string(file)) } - template, err := flixkit.ParseFlix(string(file)) if err != nil { - return nil, fmt.Errorf("could not parse flix") + return nil, fmt.Errorf("could not find or parse flix template") } cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) @@ -157,7 +81,7 @@ var pathCommand = &command.Command{ BlockID: flags.BlockID, BlockHeight: flags.BlockHeight, } - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args, "", flow, scriptsFlags) } else { transactionFlags := transactions.Flags{ ArgsJSON: flags.ArgsJSON, @@ -169,13 +93,7 @@ var pathCommand = &command.Command{ Exclude: flags.Exclude, GasLimit: flags.GasLimit, } - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args, "", flow, state, transactionFlags) } }, } - -func init() { - idCommand.AddToParent(Cmd) - nameCommand.AddToParent(Cmd) - pathCommand.AddToParent(Cmd) -} From 1ba08749577406fca0ca0036f1fe420f1c19a990 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 2 Aug 2023 13:28:50 -0700 Subject: [PATCH 14/30] Consolidate commands and detect type --- cmd/flow/main.go | 8 ++- internal/flix/flix.go | 152 ++++++++++++++++++++++++++---------------- 2 files changed, 102 insertions(+), 58 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index fdf370bd5..3a82b8bca 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -71,6 +71,9 @@ func main() { super.SetupCommand.AddToParent(cmd) super.DevCommand.AddToParent(cmd) + // flix commands + flix.FlixCommand.AddToParent(cmd) + // structured commands cmd.AddCommand(settings.Cmd) cmd.AddCommand(cadence.Cmd) @@ -87,7 +90,6 @@ func main() { cmd.AddCommand(config.Cmd) cmd.AddCommand(signatures.Cmd) cmd.AddCommand(snapshot.Cmd) - cmd.AddCommand(flix.FlixCommand.Cmd) command.InitFlags(cmd) cmd.AddGroup(&cobra.Group{ @@ -114,6 +116,10 @@ func main() { ID: "security", Title: "🔒 Flow Security", }) + cmd.AddGroup(&cobra.Group{ + ID: "flix", + Title: "Flow Interaction Templates (FLIX)", + }) cmd.SetUsageTemplate(command.UsageTemplate) diff --git a/internal/flix/flix.go b/internal/flix/flix.go index 2053c09a1..17c45a8c6 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -4,16 +4,18 @@ import ( "context" "fmt" "os" + "regexp" + "strings" + + "github.com/onflow/flixkit-go" "github.com/onflow/flow-cli/flowkit/output" "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/internal/scripts" + "github.com/onflow/flow-cli/internal/transactions" "github.com/onflow/flow-cli/flowkit" - "github.com/onflow/flixkit-go" - - "github.com/onflow/flow-cli/internal/scripts" - "github.com/onflow/flow-cli/internal/transactions" "github.com/spf13/cobra" ) @@ -28,72 +30,108 @@ type flixFlags struct { Include []string `default:"" flag:"include" info:"Fields to include in the output"` Exclude []string `default:"" flag:"exclude" info:"Fields to exclude from the output (events)"` GasLimit uint64 `default:"1000" flag:"gas-limit" info:"transaction gas limit"` - ID string `default:"" flag:"id" info:"id of the flix"` - Name string `default:"" flag:"name" info:"name of the flix"` - Path string `default:"" flag:"path" info:"path to the flix file"` } var flags = flixFlags{} var FlixCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "flix [ ...]", - Short: "Execute flix operation with given id, name or path", - Args: cobra.MinimumNArgs(1), - Example: `flow flix --id 123`, + Use: "flix ", + Short: "Execute flix with given id, name or path", + Example: "flow flix multiply 2 3 --network testnet", + Args: cobra.ArbitraryArgs, + GroupID: "flix", }, Flags: &flags, - RunS: func(args []string, _ command.GlobalFlags, _ output.Logger, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { - flixService := flixkit.NewFlixService(&flixkit.Config{}) - ctx := context.Background() - var template *flixkit.FlowInteractionTemplate - - if flags.ID != "" { - template, err = flixService.GetFlixByID(ctx, flags.ID) - if err != nil { - return nil, fmt.Errorf("could not find flix with id %s", flags.ID) - } - } else if flags.Name != "" { - template, err = flixService.GetFlix(ctx, flags.Name) - if err != nil { - return nil, fmt.Errorf("could not find flix with name %s", flags.Name) - } - } else if flags.Path != "" { - file, err := os.ReadFile(flags.Path) - if err != nil { - return nil, fmt.Errorf("could not read file") - } - template, err = flixkit.ParseFlix(string(file)) - } + RunS: execute, +} + +type flixTypes string +const ( + name flixTypes = "name" + path flixTypes = "path" + id flixTypes = "id" +) + +func isHex(s string) bool { + match, _ := regexp.MatchString("^[a-fA-F0-9]+$", s) + return match +} + +func isPath(path string) bool { + return strings.HasPrefix(path, "./") +} + +func getType(s string) flixTypes { + switch { + case isPath(s): + return path + case isHex(s): + return id + default: + return name + } +} + +func execute( + args []string, + _ command.GlobalFlags, + _ output.Logger, + flow flowkit.Services, + state *flowkit.State, +) (result command.Result, err error) { + flixService := flixkit.NewFlixService(&flixkit.Config{}) + ctx := context.Background() + var template *flixkit.FlowInteractionTemplate + flixQuery := args[0] + flixQueryType := getType(flixQuery) + + if flixQueryType == id { + template, err = flixService.GetFlixByID(ctx, flixQuery) if err != nil { - return nil, fmt.Errorf("could not find or parse flix template") + return nil, fmt.Errorf("could not find flix with id %s", flixQuery) } - - cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) + } else if flixQueryType == name { + template, err = flixService.GetFlix(ctx, flixQuery) if err != nil { - return nil, fmt.Errorf("could not replace imports") + return nil, fmt.Errorf("could not find flix with name %s", flixQuery) } + } else if flixQueryType == path { + file, err := os.ReadFile(flixQuery) + if err != nil { + return nil, fmt.Errorf("could not read file") + } + template, err = flixkit.ParseFlix(string(file)) + } + + if err != nil { + return nil, fmt.Errorf("could not find or parse flix template") + } - if template.IsScript() { - scriptsFlags := scripts.Flags{ - ArgsJSON: flags.ArgsJSON, - BlockID: flags.BlockID, - BlockHeight: flags.BlockHeight, - } - return scripts.SendScript([]byte(cadenceWithImportsReplaced), args, "", flow, scriptsFlags) - } else { - transactionFlags := transactions.Flags{ - ArgsJSON: flags.ArgsJSON, - Signer: flags.Signer, - Proposer: flags.Proposer, - Payer: flags.Payer, - Authorizers: flags.Authorizers, - Include: flags.Include, - Exclude: flags.Exclude, - GasLimit: flags.GasLimit, - } - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args, "", flow, state, transactionFlags) + cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) + if err != nil { + return nil, fmt.Errorf("could not replace imports") + } + + if template.IsScript() { + scriptsFlags := scripts.Flags{ + ArgsJSON: flags.ArgsJSON, + BlockID: flags.BlockID, + BlockHeight: flags.BlockHeight, } - }, + return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) + } else { + transactionFlags := transactions.Flags{ + ArgsJSON: flags.ArgsJSON, + Signer: flags.Signer, + Proposer: flags.Proposer, + Payer: flags.Payer, + Authorizers: flags.Authorizers, + Include: flags.Include, + Exclude: flags.Exclude, + GasLimit: flags.GasLimit, + } + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) + } } From 68d764cc70812b610964d426f698e99210058004 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 2 Aug 2023 13:34:15 -0700 Subject: [PATCH 15/30] Use logger --- internal/flix/flix.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/internal/flix/flix.go b/internal/flix/flix.go index 17c45a8c6..dfa83740a 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -77,7 +77,7 @@ func getType(s string) flixTypes { func execute( args []string, _ command.GlobalFlags, - _ output.Logger, + logger output.Logger, flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { @@ -90,28 +90,33 @@ func execute( if flixQueryType == id { template, err = flixService.GetFlixByID(ctx, flixQuery) if err != nil { - return nil, fmt.Errorf("could not find flix with id %s", flixQuery) + logger.Error(fmt.Sprintf("could not find flix with id %s", flixQuery)) + return nil, err } } else if flixQueryType == name { template, err = flixService.GetFlix(ctx, flixQuery) if err != nil { - return nil, fmt.Errorf("could not find flix with name %s", flixQuery) + logger.Error(fmt.Sprintf("could not find flix with name %s", flixQuery)) + return nil, err } } else if flixQueryType == path { file, err := os.ReadFile(flixQuery) if err != nil { - return nil, fmt.Errorf("could not read file") + logger.Error(fmt.Sprintf("could not read flix file %s", flixQuery)) + return nil, err } template, err = flixkit.ParseFlix(string(file)) } if err != nil { - return nil, fmt.Errorf("could not find or parse flix template") + logger.Error("could not find or parse flix template") + return nil, err } cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) if err != nil { - return nil, fmt.Errorf("could not replace imports") + logger.Error("could not replace imports") + return nil, err } if template.IsScript() { From 3f6c8030504864528c55d1b3c1751dd067547a70 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 2 Aug 2023 13:45:07 -0700 Subject: [PATCH 16/30] Change name --- internal/flix/flix.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/flix/flix.go b/internal/flix/flix.go index dfa83740a..eba09fa38 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -46,12 +46,12 @@ var FlixCommand = &command.Command{ RunS: execute, } -type flixTypes string +type flixQueryTypes string const ( - name flixTypes = "name" - path flixTypes = "path" - id flixTypes = "id" + name flixQueryTypes = "name" + path flixQueryTypes = "path" + id flixQueryTypes = "id" ) func isHex(s string) bool { @@ -63,7 +63,7 @@ func isPath(path string) bool { return strings.HasPrefix(path, "./") } -func getType(s string) flixTypes { +func getType(s string) flixQueryTypes { switch { case isPath(s): return path From 0535db374c864674f44842f326b7514096325ec5 Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Mon, 7 Aug 2023 10:47:39 -0700 Subject: [PATCH 17/30] Update internal/flix/flix.go Co-authored-by: Gregor G. <75445744+sideninja@users.noreply.github.com> --- internal/flix/flix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/flix/flix.go b/internal/flix/flix.go index eba09fa38..23939585b 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -37,7 +37,7 @@ var flags = flixFlags{} var FlixCommand = &command.Command{ Cmd: &cobra.Command{ Use: "flix ", - Short: "Execute flix with given id, name or path", + Short: "Execute FLIX template with a given id, name, or local filename", Example: "flow flix multiply 2 3 --network testnet", Args: cobra.ArbitraryArgs, GroupID: "flix", From 3c0fe87bc11d97bc681e78ecbfbca8bc20b53f0a Mon Sep 17 00:00:00 2001 From: Chase Fleming Date: Mon, 7 Aug 2023 10:47:57 -0700 Subject: [PATCH 18/30] Update internal/flix/flix.go Co-authored-by: Gregor G. <75445744+sideninja@users.noreply.github.com> --- internal/flix/flix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/flix/flix.go b/internal/flix/flix.go index 23939585b..1e8b01412 100644 --- a/internal/flix/flix.go +++ b/internal/flix/flix.go @@ -38,7 +38,7 @@ var FlixCommand = &command.Command{ Cmd: &cobra.Command{ Use: "flix ", Short: "Execute FLIX template with a given id, name, or local filename", - Example: "flow flix multiply 2 3 --network testnet", + Example: "flow flix multiply 2 3", Args: cobra.ArbitraryArgs, GroupID: "flix", }, From 00c2866d5f8a5032f61bd8c0bcb47b05711d7e56 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 10:55:56 -0700 Subject: [PATCH 19/30] Clean up unnecessary func --- internal/scripts/execute.go | 18 ++++++++---------- internal/transactions/send.go | 4 +--- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/internal/scripts/execute.go b/internal/scripts/execute.go index 19def616b..050518951 100644 --- a/internal/scripts/execute.go +++ b/internal/scripts/execute.go @@ -58,7 +58,14 @@ func execute( readerWriter flowkit.ReaderWriter, flow flowkit.Services, ) (command.Result, error) { - return executeLocalScript(args, args[0], readerWriter, flow) + filename := args[0] + + code, err := readerWriter.ReadFile(filename) + if err != nil { + return nil, fmt.Errorf("error loading script file: %w", err) + } + + return SendScript(code, args[1:], filename, flow, flags) } func SendScript(code []byte, argsArr []string, location string, flow flowkit.Services, scriptFlags Flags) (command.Result, error) { @@ -98,12 +105,3 @@ func SendScript(code []byte, argsArr []string, location string, flow flowkit.Ser return &scriptResult{value}, nil } - -func executeLocalScript(args []string, filename string, readerWriter flowkit.ReaderWriter, flow flowkit.Services) (command.Result, error) { - code, err := readerWriter.ReadFile(filename) - if err != nil { - return nil, fmt.Errorf("error loading script file: %w", err) - } - - return SendScript(code, args[1:], filename, flow, flags) -} diff --git a/internal/transactions/send.go b/internal/transactions/send.go index 9b11d5e2c..61522a789 100644 --- a/internal/transactions/send.go +++ b/internal/transactions/send.go @@ -64,10 +64,8 @@ func send( flow flowkit.Services, state *flowkit.State, ) (result command.Result, err error) { - return executeLocalTransaction(args, args[0], flow, state) -} + filename := args[0] -func executeLocalTransaction(args []string, filename string, flow flowkit.Services, state *flowkit.State) (result command.Result, err error) { code, err := state.ReadFile(filename) if err != nil { return nil, fmt.Errorf("error loading transaction file: %w", err) From 3e09369d02ed312a01a3a9d5d6709d8677fa3961 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:29:34 -0700 Subject: [PATCH 20/30] Move to super commands --- cmd/flow/main.go | 6 +----- internal/{flix => super}/flix.go | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 16 deletions(-) rename internal/{flix => super}/flix.go (93%) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 3a82b8bca..9613a5d08 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -22,8 +22,6 @@ package main import ( "os" - "github.com/onflow/flow-cli/internal/flix" - "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/accounts" @@ -70,9 +68,7 @@ func main() { // super commands super.SetupCommand.AddToParent(cmd) super.DevCommand.AddToParent(cmd) - - // flix commands - flix.FlixCommand.AddToParent(cmd) + super.FlixCommand.AddToParent(cmd) // structured commands cmd.AddCommand(settings.Cmd) diff --git a/internal/flix/flix.go b/internal/super/flix.go similarity index 93% rename from internal/flix/flix.go rename to internal/super/flix.go index 1e8b01412..095e87b4e 100644 --- a/internal/flix/flix.go +++ b/internal/super/flix.go @@ -1,4 +1,4 @@ -package flix +package super import ( "context" @@ -40,7 +40,7 @@ var FlixCommand = &command.Command{ Short: "Execute FLIX template with a given id, name, or local filename", Example: "flow flix multiply 2 3", Args: cobra.ArbitraryArgs, - GroupID: "flix", + GroupID: "super", }, Flags: &flags, RunS: execute, @@ -49,9 +49,9 @@ var FlixCommand = &command.Command{ type flixQueryTypes string const ( - name flixQueryTypes = "name" - path flixQueryTypes = "path" - id flixQueryTypes = "id" + flixName flixQueryTypes = "name" + flixPath flixQueryTypes = "path" + flixId flixQueryTypes = "id" ) func isHex(s string) bool { @@ -66,11 +66,11 @@ func isPath(path string) bool { func getType(s string) flixQueryTypes { switch { case isPath(s): - return path + return flixPath case isHex(s): - return id + return flixId default: - return name + return flixName } } @@ -87,19 +87,19 @@ func execute( flixQuery := args[0] flixQueryType := getType(flixQuery) - if flixQueryType == id { + if flixQueryType == flixId { template, err = flixService.GetFlixByID(ctx, flixQuery) if err != nil { logger.Error(fmt.Sprintf("could not find flix with id %s", flixQuery)) return nil, err } - } else if flixQueryType == name { + } else if flixQueryType == flixName { template, err = flixService.GetFlix(ctx, flixQuery) if err != nil { logger.Error(fmt.Sprintf("could not find flix with name %s", flixQuery)) return nil, err } - } else if flixQueryType == path { + } else if flixQueryType == flixPath { file, err := os.ReadFile(flixQuery) if err != nil { logger.Error(fmt.Sprintf("could not read flix file %s", flixQuery)) From f19c8b95889f58492ca54611483f5c1588a95f2f Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:40:11 -0700 Subject: [PATCH 21/30] Use switch instead --- internal/super/flix.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index 095e87b4e..adca3cc01 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -85,27 +85,30 @@ func execute( ctx := context.Background() var template *flixkit.FlowInteractionTemplate flixQuery := args[0] - flixQueryType := getType(flixQuery) - if flixQueryType == flixId { + switch getType(flixQuery) { + case flixId: template, err = flixService.GetFlixByID(ctx, flixQuery) if err != nil { logger.Error(fmt.Sprintf("could not find flix with id %s", flixQuery)) return nil, err } - } else if flixQueryType == flixName { + case flixName: template, err = flixService.GetFlix(ctx, flixQuery) if err != nil { logger.Error(fmt.Sprintf("could not find flix with name %s", flixQuery)) return nil, err } - } else if flixQueryType == flixPath { + case flixPath: file, err := os.ReadFile(flixQuery) if err != nil { logger.Error(fmt.Sprintf("could not read flix file %s", flixQuery)) return nil, err } template, err = flixkit.ParseFlix(string(file)) + default: + logger.Error("invalid flix query type") + return nil, err } if err != nil { From fe64ba97835d6e987cec68c20cf1eeb751bdeb95 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 13:42:06 -0700 Subject: [PATCH 22/30] Remove nesting --- internal/super/flix.go | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index adca3cc01..400e6b2af 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -129,17 +129,17 @@ func execute( BlockHeight: flags.BlockHeight, } return scripts.SendScript([]byte(cadenceWithImportsReplaced), args[1:], "", flow, scriptsFlags) - } else { - transactionFlags := transactions.Flags{ - ArgsJSON: flags.ArgsJSON, - Signer: flags.Signer, - Proposer: flags.Proposer, - Payer: flags.Payer, - Authorizers: flags.Authorizers, - Include: flags.Include, - Exclude: flags.Exclude, - GasLimit: flags.GasLimit, - } - return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) } + + transactionFlags := transactions.Flags{ + ArgsJSON: flags.ArgsJSON, + Signer: flags.Signer, + Proposer: flags.Proposer, + Payer: flags.Payer, + Authorizers: flags.Authorizers, + Include: flags.Include, + Exclude: flags.Exclude, + GasLimit: flags.GasLimit, + } + return transactions.SendTransaction([]byte(cadenceWithImportsReplaced), args[1:], "", flow, state, transactionFlags) } From 7d4e88886230ea155f141790eedd7b7792ff0ec9 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:02:07 -0700 Subject: [PATCH 23/30] Use versioned package --- go.mod | 3 +-- go.sum | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 5f960091f..a98ebaf40 100644 --- a/go.mod +++ b/go.mod @@ -147,7 +147,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onflow/atree v0.6.0 // indirect github.com/onflow/cadence-tools/lint v0.9.0 // indirect - github.com/onflow/flixkit-go v0.0.0 + github.com/onflow/flixkit-go v0.1.0 // indirect github.com/onflow/flow-archive v1.3.4-0.20230503192214-9e81e82d4dcc // indirect github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.3 // indirect github.com/onflow/flow-ft/lib/go/contracts v0.7.0 // indirect @@ -233,4 +233,3 @@ require ( ) replace github.com/onflow/flow-cli/flowkit => ./flowkit -replace github.com/onflow/flixkit-go => ../flixkit-go \ No newline at end of file diff --git a/go.sum b/go.sum index 5dbc5b0b8..7a92c53cb 100644 --- a/go.sum +++ b/go.sum @@ -800,6 +800,8 @@ github.com/onflow/cadence-tools/test v0.9.2 h1:tb+4/ZyOYGhH4+lFnrkGfEYiT29CkE24z github.com/onflow/cadence-tools/test v0.9.2/go.mod h1:Cb2uu5u4eKgITDBTl4b13pa9Fa5M053Yi2Mdr7Ib3W0= github.com/onflow/fcl-dev-wallet v0.7.2 h1:ZwhpzDakcZn9rHiIr52LwkdPh1MpUPbxA/PwCVaZ2SA= github.com/onflow/fcl-dev-wallet v0.7.2/go.mod h1:kc42jkiuoPJmxMRFjfbRO9XvnR/3XLheaOerxVMDTiw= +github.com/onflow/flixkit-go v0.1.0 h1:3nH+1z+D+0YlmEJk9zYtvD8p4eUl2wJtiV6ZCgM7vYE= +github.com/onflow/flixkit-go v0.1.0/go.mod h1:gPffHQ6jDyuNtLG6W9C6FGvDZmcOb9CkvsJYKY0Opc4= github.com/onflow/flow-archive v1.3.4-0.20230503192214-9e81e82d4dcc h1:C4ZniFeOv+pHlDLJdGc/4e3NklSjVuvaXKN47980gnY= github.com/onflow/flow-archive v1.3.4-0.20230503192214-9e81e82d4dcc/go.mod h1:UPsvKk/37Atosif4wlBl3gsLbGJyGpdXYpXDsWtMVBE= github.com/onflow/flow-core-contracts/lib/go/contracts v1.2.3 h1:wV+gcgOY0oJK4HLZQYQoK+mm09rW1XSxf83yqJwj0n4= From 760cef5fd5e832a9f49e92902795168387568736 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:16:48 -0700 Subject: [PATCH 24/30] Change flix query type checks --- internal/super/flix.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index 400e6b2af..abfc2daad 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -2,10 +2,9 @@ package super import ( "context" + "encoding/hex" "fmt" "os" - "regexp" - "strings" "github.com/onflow/flixkit-go" @@ -54,13 +53,17 @@ const ( flixId flixQueryTypes = "id" ) -func isHex(s string) bool { - match, _ := regexp.MatchString("^[a-fA-F0-9]+$", s) - return match +func isHex(str string) bool { + if len(str) != 64 { + return false + } + _, err := hex.DecodeString(str) + return err == nil } func isPath(path string) bool { - return strings.HasPrefix(path, "./") + _, err := os.Stat(path) + return err == nil } func getType(s string) flixQueryTypes { From 5e57ad23ac9155b94e22c43d81b72276d1a06dfe Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:23:29 -0700 Subject: [PATCH 25/30] Add license header --- internal/super/flix.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/internal/super/flix.go b/internal/super/flix.go index abfc2daad..2e3c02a44 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019 Dapper Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package super import ( From d6de991e0fc354df8f89a05299677bc2835c60c2 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:35:48 -0700 Subject: [PATCH 26/30] Remove unnecessary check --- internal/super/flix.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index 2e3c02a44..ca16dd2da 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -132,11 +132,6 @@ func execute( return nil, err } - if err != nil { - logger.Error("could not find or parse flix template") - return nil, err - } - cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) if err != nil { logger.Error("could not replace imports") From ceb6cc60b6cddedbca208c79f786483ae06bb2e8 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:41:48 -0700 Subject: [PATCH 27/30] Improve query checks --- internal/super/flix.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index ca16dd2da..df8c080ce 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -76,12 +76,18 @@ func isHex(str string) bool { return false } _, err := hex.DecodeString(str) - return err == nil + if err != nil { + return false + } + return true } func isPath(path string) bool { _, err := os.Stat(path) - return err == nil + if err != nil { + return false + } + return true } func getType(s string) flixQueryTypes { From 972c23e4a6c2f7ee0442b707986f9b0ca28d8f76 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:48:30 -0700 Subject: [PATCH 28/30] Return error --- internal/super/flix.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index df8c080ce..cb20dde23 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -135,7 +135,7 @@ func execute( template, err = flixkit.ParseFlix(string(file)) default: logger.Error("invalid flix query type") - return nil, err + return nil, fmt.Errorf("invalid flix query type: %s", flixQuery) } cadenceWithImportsReplaced, err := template.GetAndReplaceCadenceImports(flow.Network().Name) From 61dbe6f76950161052bcdd61012990c563cbe354 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Mon, 7 Aug 2023 15:54:15 -0700 Subject: [PATCH 29/30] return errors --- internal/super/flix.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/internal/super/flix.go b/internal/super/flix.go index cb20dde23..b8dc0f153 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -117,24 +117,26 @@ func execute( case flixId: template, err = flixService.GetFlixByID(ctx, flixQuery) if err != nil { - logger.Error(fmt.Sprintf("could not find flix with id %s", flixQuery)) - return nil, err + return nil, fmt.Errorf("could not find flix with id %s: %w", flixQuery, err) } + case flixName: template, err = flixService.GetFlix(ctx, flixQuery) if err != nil { - logger.Error(fmt.Sprintf("could not find flix with name %s", flixQuery)) - return nil, err + return nil, fmt.Errorf("could not find flix with name %s: %w", flixQuery, err) } + case flixPath: file, err := os.ReadFile(flixQuery) if err != nil { - logger.Error(fmt.Sprintf("could not read flix file %s", flixQuery)) - return nil, err + return nil, fmt.Errorf("could not read flix file %s: %w", flixQuery, err) } template, err = flixkit.ParseFlix(string(file)) + if err != nil { + return nil, fmt.Errorf("could not parse flix from file %s: %w", flixQuery, err) + } + default: - logger.Error("invalid flix query type") return nil, fmt.Errorf("invalid flix query type: %s", flixQuery) } From b5e363e92cdbca984f7822be1aec8c2cb453ecb1 Mon Sep 17 00:00:00 2001 From: Chase Fleming <1666730+chasefleming@users.noreply.github.com> Date: Wed, 9 Aug 2023 09:54:46 -0700 Subject: [PATCH 30/30] Remove unnecessary group and refactor --- cmd/flow/main.go | 4 ---- internal/super/flix.go | 10 ++-------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 9613a5d08..6e3405b0e 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -112,10 +112,6 @@ func main() { ID: "security", Title: "🔒 Flow Security", }) - cmd.AddGroup(&cobra.Group{ - ID: "flix", - Title: "Flow Interaction Templates (FLIX)", - }) cmd.SetUsageTemplate(command.UsageTemplate) diff --git a/internal/super/flix.go b/internal/super/flix.go index b8dc0f153..4c53d261d 100644 --- a/internal/super/flix.go +++ b/internal/super/flix.go @@ -76,18 +76,12 @@ func isHex(str string) bool { return false } _, err := hex.DecodeString(str) - if err != nil { - return false - } - return true + return err == nil } func isPath(path string) bool { _, err := os.Stat(path) - if err != nil { - return false - } - return true + return err == nil } func getType(s string) flixQueryTypes {