From 2a0a2b1a410dd7f1df10c365c78a8c4d395bc913 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 16:42:55 +0300 Subject: [PATCH 001/171] Create Status service --- pkg/flowcli/services/status.go | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 pkg/flowcli/services/status.go diff --git a/pkg/flowcli/services/status.go b/pkg/flowcli/services/status.go new file mode 100644 index 000000000..1000810b2 --- /dev/null +++ b/pkg/flowcli/services/status.go @@ -0,0 +1,46 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 services + +import ( + "github.com/onflow/flow-cli/pkg/flowcli/gateway" + "github.com/onflow/flow-cli/pkg/flowcli/output" +) + +// Status is a service that handles status of access node +type Status struct { + gateway gateway.Gateway + logger output.Logger +} + +// NewPing returns a new ping service +func NewStatus( + gateway gateway.Gateway, + logger output.Logger, +) *Status { + return &Status{ + gateway: gateway, + logger: logger, + } +} + +func (e *Status) Ping() error { + return e.gateway.Ping() +} + From 009afc681b92e384d6ab6a7b9c631150f1628b91 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 16:43:52 +0300 Subject: [PATCH 002/171] Add Ping implementations to gateways --- pkg/flowcli/gateway/emulator.go | 4 ++++ pkg/flowcli/gateway/gateway.go | 1 + pkg/flowcli/gateway/grpc.go | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/pkg/flowcli/gateway/emulator.go b/pkg/flowcli/gateway/emulator.go index 57b0d5198..d6e1d264e 100644 --- a/pkg/flowcli/gateway/emulator.go +++ b/pkg/flowcli/gateway/emulator.go @@ -63,6 +63,10 @@ func (g *EmulatorGateway) GetTransaction(id flow.Identifier) (*flow.Transaction, return g.emulator.GetTransaction(id) } +func (g *EmulatorGateway) Ping() error { + return nil +} + func (g *EmulatorGateway) ExecuteScript(script []byte, arguments []cadence.Value) (cadence.Value, error) { return nil, fmt.Errorf("Not Supported Yet") } diff --git a/pkg/flowcli/gateway/gateway.go b/pkg/flowcli/gateway/gateway.go index 35baec85a..598a25514 100644 --- a/pkg/flowcli/gateway/gateway.go +++ b/pkg/flowcli/gateway/gateway.go @@ -37,4 +37,5 @@ type Gateway interface { GetBlockByID(flow.Identifier) (*flow.Block, error) GetEvents(string, uint64, uint64) ([]client.BlockEvents, error) GetCollection(flow.Identifier) (*flow.Collection, error) + Ping() (error) } diff --git a/pkg/flowcli/gateway/grpc.go b/pkg/flowcli/gateway/grpc.go index 4fae9ac4b..3385e1ffd 100644 --- a/pkg/flowcli/gateway/grpc.go +++ b/pkg/flowcli/gateway/grpc.go @@ -169,3 +169,9 @@ func (g *GrpcGateway) GetEvents( func (g *GrpcGateway) GetCollection(id flow.Identifier) (*flow.Collection, error) { return g.client.GetCollection(g.ctx, id) } + +// Ping is used to check if the access node is alive and healthy +func (g *GrpcGateway) Ping() error { + return g.client.Ping(g.ctx) +} + From ffe5d79cd8d1960a5e2a89ef1493dff98e6f379f Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 16:44:03 +0300 Subject: [PATCH 003/171] Add Status service to a list --- pkg/flowcli/services/services.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/flowcli/services/services.go b/pkg/flowcli/services/services.go index c93cf25aa..40fa22155 100644 --- a/pkg/flowcli/services/services.go +++ b/pkg/flowcli/services/services.go @@ -35,6 +35,7 @@ type Services struct { Collections *Collections Project *Project Blocks *Blocks + Status *Status } // NewServices returns a new services collection for a project, @@ -53,5 +54,6 @@ func NewServices( Collections: NewCollections(gateway, proj, logger), Project: NewProject(gateway, proj, logger), Blocks: NewBlocks(gateway, proj, logger), + Status: NewStatus(gateway, logger), } } From e92cb5dd4bbed43a80d524c312099572bbb9779b Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 16:44:23 +0300 Subject: [PATCH 004/171] Add status command --- cmd/flow/main.go | 2 + internal/status/status.go | 80 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 internal/status/status.go diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 93cbf7f6c..cbcf3981a 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -33,6 +33,7 @@ import ( "github.com/onflow/flow-cli/internal/keys" "github.com/onflow/flow-cli/internal/project" "github.com/onflow/flow-cli/internal/scripts" + "github.com/onflow/flow-cli/internal/status" "github.com/onflow/flow-cli/internal/transactions" "github.com/onflow/flow-cli/internal/version" "github.com/onflow/flow-cli/pkg/flowcli/util" @@ -46,6 +47,7 @@ func main() { // hot commands config.InitCommand.AddToParent(cmd) + status.InitCommand.AddToParent(cmd) // structured commands cmd.AddCommand(cadence.Cmd) diff --git a/internal/status/status.go b/internal/status/status.go new file mode 100644 index 000000000..75c1d58c3 --- /dev/null +++ b/internal/status/status.go @@ -0,0 +1,80 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 status + +import ( + "fmt" + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type FlagsStatus struct { +} + +var statusFlags = FlagsStatus{} + +const ( + NetworkOnline = "ONLINE" + NetworkOffline = "OFFLINE" +) + +var InitCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "status", + Short: "Display status of network", + }, + Flags: &statusFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + err := services.Status.Ping() + if err != nil { + return &Result{NetworkOffline}, nil + } + + return &Result{NetworkOnline}, nil + }, +} + +// Result structure +type Result struct { + status string +} + +func (r *Result) String() string { + icon := "🔴" + if r.status == NetworkOnline { + icon = "🟢" + } + return fmt.Sprintf("Network is: %s %s", icon, r.status) +} + +// JSON convert result to JSON +func (r *Result) JSON() interface{} { + return r +} + +// Oneliner show result as one liner grep friendly +func (r *Result) Oneliner() string { + return r.status +} From ca77910145b90666930171d4784bdae8fbb10cd2 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 17:06:13 +0300 Subject: [PATCH 005/171] Create basic docs for status command --- docs/get-status.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 docs/get-status.md diff --git a/docs/get-status.md b/docs/get-status.md new file mode 100644 index 000000000..3d9476747 --- /dev/null +++ b/docs/get-status.md @@ -0,0 +1,29 @@ +--- +title: Get Network Status +sidebar_title: Network Status +description: How to get access node status from the command line +--- + +The Flow CLI provides a command to get network status of specified Flow Access Node + +```shell +flow status +``` + +## Example Usage +```shell +> flow status --network mainnet + +Network is: ONLINE +``` + +## Options + +### Network + +- Flag: `--network` +- Short Flag: `-n` +- Valid inputs: the name of a network defined in the configuration (`flow.json`) + +Specify which network you want the command to use for execution. + From 0b9d1208e30298dfc1dec66b35f337e83e572e3b Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 17:50:34 +0300 Subject: [PATCH 006/171] Update example in documentation --- docs/get-status.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/get-status.md b/docs/get-status.md index 3d9476747..752bc2880 100644 --- a/docs/get-status.md +++ b/docs/get-status.md @@ -1,6 +1,6 @@ --- -title: Get Network Status -sidebar_title: Network Status +title: Get Network Status +sidebar_title: Network Status description: How to get access node status from the command line --- @@ -11,10 +11,10 @@ flow status ``` ## Example Usage + ```shell > flow status --network mainnet - -Network is: ONLINE +mainnet access node at access.mainnet.nodes.onflow.org:9000 is 🟢 ONLINE ``` ## Options From f971b85293634fd86ffa94d19ea39ab21249308d Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 7 Apr 2021 17:50:52 +0300 Subject: [PATCH 007/171] Add host resolver. Update output formatting --- internal/status/status.go | 50 ++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/internal/status/status.go b/internal/status/status.go index 75c1d58c3..79e18ee3e 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -20,9 +20,12 @@ package status import ( "fmt" + "github.com/fatih/color" "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" "github.com/spf13/cobra" + "strings" ) type FlagsStatus struct { @@ -31,7 +34,7 @@ type FlagsStatus struct { var statusFlags = FlagsStatus{} const ( - NetworkOnline = "ONLINE" + NetworkOnline = "ONLINE" NetworkOffline = "OFFLINE" ) @@ -47,26 +50,61 @@ var InitCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - err := services.Status.Ping() + // Get network name from global flag + network := globalFlags.Network + if network == "" { + network = "emulator" + } + + config := globalFlags.ConfigPath + proj, err := project.Load(config) + + if err != nil { + return nil, fmt.Errorf("project can't be loaded from specified config path") + } + + net := proj.NetworkByName(network) + accessNode := net.Host + + err = services.Status.Ping() if err != nil { - return &Result{NetworkOffline}, nil + return &Result{ + network, + NetworkOffline, + accessNode, + }, nil } - return &Result{NetworkOnline}, nil + return &Result{ + network, + NetworkOnline, + accessNode, + }, nil }, } // Result structure type Result struct { - status string + network string + status string + accessNode string } func (r *Result) String() string { icon := "🔴" + statusMessage := color.RedString(r.status) if r.status == NetworkOnline { icon = "🟢" + statusMessage = color.GreenString(r.status) } - return fmt.Sprintf("Network is: %s %s", icon, r.status) + return strings.Join([]string{ + color.YellowString(r.network), + "access node at", + color.CyanString(r.accessNode), + "is", + icon, + statusMessage, + }," ") } // JSON convert result to JSON From ac7fb34643d67e1457cc4b3e4886ec4abd990853 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 7 Apr 2021 17:10:19 +0200 Subject: [PATCH 008/171] wip deployments format --- pkg/flowcli/config/config.go | 2 -- pkg/flowcli/config/json/deploy.go | 30 ++++++++++++++++++++------ pkg/flowcli/config/json/deploy_test.go | 18 ++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index d6c914c95..837ae8556 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -128,8 +128,6 @@ func (c *Contracts) GetByNameAndNetwork(name string, network string) Contract { return contracts[0] } -// TODO: this filtering can cause error if not found, better to refactor to returning - // GetByName get contract by name func (c *Contracts) GetByName(name string) *Contract { for _, contract := range *c { diff --git a/pkg/flowcli/config/json/deploy.go b/pkg/flowcli/config/json/deploy.go index fcc5145be..c21d4aa24 100644 --- a/pkg/flowcli/config/json/deploy.go +++ b/pkg/flowcli/config/json/deploy.go @@ -21,6 +21,8 @@ package json import ( "encoding/json" + "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/flow-cli/pkg/flowcli/config" ) @@ -64,20 +66,36 @@ func transformDeploymentsToJSON(deployments config.Deployments) jsonDeployments return jsonDeployments } -type Simple map[string][]string +type advanced struct { + name string + args []flowcli.CadenceArgument +} -type jsonDeploy struct { - Simple +type deployment struct { + simple string + advanced advanced } +type jsonDeploy map[string][]deployment + func (j *jsonDeploy) UnmarshalJSON(b []byte) error { - var simple map[string][]string + var simple Simple + var advanced advancedArgs + // simple err := json.Unmarshal(b, &simple) - if err != nil { + if err == nil { + j.Simple = simple + return nil + } + + // advanced + err = json.Unmarshal(b, &advanced) + if err == nil { + j.AdvancedArgs = advanced + } else { return err } - j.Simple = simple return nil } diff --git a/pkg/flowcli/config/json/deploy_test.go b/pkg/flowcli/config/json/deploy_test.go index 0550579d0..3075b930a 100644 --- a/pkg/flowcli/config/json/deploy_test.go +++ b/pkg/flowcli/config/json/deploy_test.go @@ -91,3 +91,21 @@ func Test_TransformDeployToJSON(t *testing.T) { assert.Equal(t, string(b), string(x)) } + +func Test_DeploymentAdvanced(t *testing.T) { + b := []byte(`{ + "emulator": { + "alice": [ + "KittyItems", { + "name": "Kibble", + "args": [{ "type": "String", "value": "Hello World" }] + }, + "KittyItemsMarket" + ] + } + }`) + + var jsonDeployments jsonDeployments + err := json.Unmarshal(b, &jsonDeployments) + assert.NoError(t, err) +} From 2be3e215def375c52635be1e9f4f36b919a7017d Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 16:09:21 +0300 Subject: [PATCH 009/171] Refactor code according to review comments --- internal/status/status.go | 91 ++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/internal/status/status.go b/internal/status/status.go index 79e18ee3e..5cb550458 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -19,13 +19,14 @@ package status import ( + "bytes" "fmt" "github.com/fatih/color" "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" "github.com/spf13/cobra" - "strings" + "text/tabwriter" ) type FlagsStatus struct { @@ -33,9 +34,19 @@ type FlagsStatus struct { var statusFlags = FlagsStatus{} +// Result structure +type Result struct { + network string + accessNode string + connectionError error +} + const ( - NetworkOnline = "ONLINE" - NetworkOffline = "OFFLINE" + OnlineIcon = "🟢" + OnlineStatus = "ONLINE" + + OfflineIcon = "🔴" + OfflineStatus = "OFFLINE" ) var InitCommand = &command.Command{ @@ -56,63 +67,65 @@ var InitCommand = &command.Command{ network = "emulator" } - config := globalFlags.ConfigPath - proj, err := project.Load(config) + proj, err := project.Load(globalFlags.ConfigPath) if err != nil { return nil, fmt.Errorf("project can't be loaded from specified config path") } - net := proj.NetworkByName(network) - accessNode := net.Host + accessNode := proj.NetworkByName(network).Host err = services.Status.Ping() - if err != nil { - return &Result{ - network, - NetworkOffline, - accessNode, - }, nil - } - return &Result{ network, - NetworkOnline, accessNode, + err, }, nil }, } -// Result structure -type Result struct { - network string - status string - accessNode string -} - func (r *Result) String() string { - icon := "🔴" - statusMessage := color.RedString(r.status) - if r.status == NetworkOnline { - icon = "🟢" - statusMessage = color.GreenString(r.status) - } - return strings.Join([]string{ - color.YellowString(r.network), - "access node at", - color.CyanString(r.accessNode), - "is", - icon, - statusMessage, - }," ") + var b bytes.Buffer + writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + + fmt.Fprintf(writer, "Status:\t %s %s\n", r.GetStatusIcon(), r.GetStatus()) + fmt.Fprintf(writer, "Network:\t %s\n", r.network) + fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) + + writer.Flush() + return b.String() } // JSON convert result to JSON func (r *Result) JSON() interface{} { - return r + result := make(map[string]string) + + result["network"] = r.network + result["accessNode"] = r.accessNode + result["status"] = r.GetStatus() + + return result } // Oneliner show result as one liner grep friendly func (r *Result) Oneliner() string { - return r.status + return fmt.Sprintf("%s:%s", r.network, r.GetStatus()) +} + +// GetStatus returns string representation for network status +func (r *Result) GetStatus() string { + if r.connectionError == nil { + return color.GreenString("%s", OnlineStatus) + } + + return color.RedString("%s", OfflineStatus) +} + +// GetStatusIcon returns emoji icon representing network status +func (r *Result) GetStatusIcon() string { + if r.connectionError == nil { + return OnlineIcon + } + + return OfflineIcon } From caa22c6713ff285f067f76d8b23bf11068ca4aa4 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 16:09:46 +0300 Subject: [PATCH 010/171] Update example result and usage --- docs/get-status.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/get-status.md b/docs/get-status.md index 752bc2880..3c10976f0 100644 --- a/docs/get-status.md +++ b/docs/get-status.md @@ -6,15 +6,16 @@ description: How to get access node status from the command line The Flow CLI provides a command to get network status of specified Flow Access Node -```shell -flow status -``` +`flow status` ## Example Usage ```shell -> flow status --network mainnet -mainnet access node at access.mainnet.nodes.onflow.org:9000 is 🟢 ONLINE +> flow status --network testnet + +Status: 🟢 ONLINE +Network: testnet +Access Node: access.devnet.nodes.onflow.org:9000 ``` ## Options From 00c1a48d10a9bdb1478d6a078cfed1952977cff6 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:10:05 +0200 Subject: [PATCH 011/171] added contract deployment type --- pkg/flowcli/config/config.go | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 837ae8556..9963c61e8 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -21,6 +21,8 @@ package config import ( "errors" + "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" ) @@ -48,9 +50,15 @@ type Network struct { // Deploy defines the configuration for a contract deployment. type Deploy struct { - Network string // network name to deploy to - Account string // account name to which to deploy to - Contracts []string // contracts names to deploy + Network string // network name to deploy to + Account string // account name to which to deploy to + Contracts []ContractDeployment // contracts to deploy +} + +// ContractDeployment defines the deployment of the contract with possible args +type ContractDeployment struct { + Name string + Args []flowcli.CadenceArgument } // Contract defines the configuration for a Cadence contract. @@ -189,7 +197,7 @@ func (a *Accounts) AddOrUpdate(name string, account Account) { // GetByNetwork get all deployments by network func (d *Deployments) GetByNetwork(network string) Deployments { - var deployments []Deploy + var deployments Deployments for _, deploy := range *d { if deploy.Network == network { @@ -201,8 +209,8 @@ func (d *Deployments) GetByNetwork(network string) Deployments { } // GetByAccountAndNetwork get deploy by account and network -func (d *Deployments) GetByAccountAndNetwork(account string, network string) []Deploy { - var deployments []Deploy +func (d *Deployments) GetByAccountAndNetwork(account string, network string) Deployments { + var deployments Deployments for _, deploy := range *d { if deploy.Network == network && deploy.Account == account { From d3629f868e397771e9a1d202ee6b46a35b056151 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:10:19 +0200 Subject: [PATCH 012/171] fixed tests with new structure --- pkg/flowcli/config/config_test.go | 34 ++++++++++---- pkg/flowcli/config/json/deploy_test.go | 65 +++++++++++++++++++------- pkg/flowcli/project/project_test.go | 65 +++++++++++++++++--------- 3 files changed, 118 insertions(+), 46 deletions(-) diff --git a/pkg/flowcli/config/config_test.go b/pkg/flowcli/config/config_test.go index a3c784d46..df586edff 100644 --- a/pkg/flowcli/config/config_test.go +++ b/pkg/flowcli/config/config_test.go @@ -20,6 +20,8 @@ package config_test import ( "testing" + "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/stretchr/testify/assert" @@ -62,15 +64,26 @@ func generateComplexConfig() config.Config { Deployments: config.Deployments{{ Network: "emulator", Account: "emulator-account", - Contracts: []string{"KittyItems", "KittyItemsMarket"}, + Contracts: []config.ContractDeployment{{Name: "KittyItems", Args: nil}, {Name: "KittyItemsMarket", Args: nil}}, }, { - Network: "emulator", - Account: "account-4", - Contracts: []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"}, + Network: "emulator", + Account: "account-4", + Contracts: []config.ContractDeployment{ + {Name: "FungibleToken", Args: nil}, + {Name: "NonFungibleToken", Args: nil}, + {Name: "Kibble", Args: nil}, + {Name: "KittyItems", Args: nil}, + {Name: "KittyItemsMarket", Args: nil}, + }, }, { - Network: "testnet", - Account: "account-2", - Contracts: []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"}, + Network: "testnet", + Account: "account-2", + Contracts: []config.ContractDeployment{ + {Name: "FungibleToken", Args: nil}, + {Name: "NonFungibleToken", Args: nil}, + {Name: "Kibble", Args: nil}, + {Name: "KittyItems", Args: nil}, + }, }}, Accounts: config.Accounts{{ Name: "emulator-account", @@ -159,7 +172,12 @@ func Test_GetDeploymentsByNetworkComplex(t *testing.T) { conf := generateComplexConfig() deployments := conf.Deployments.GetByAccountAndNetwork("account-2", "testnet") - assert.Equal(t, deployments[0].Contracts, []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"}) + assert.Equal(t, deployments[0].Contracts, []config.ContractDeployment{ + {Name: "FungibleToken", Args: []flowcli.CadenceArgument(nil)}, + {Name: "NonFungibleToken", Args: []flowcli.CadenceArgument(nil)}, + {Name: "Kibble", Args: []flowcli.CadenceArgument(nil)}, + {Name: "KittyItems", Args: []flowcli.CadenceArgument(nil)}, + }) } func Test_GetNetworkByNameComplex(t *testing.T) { diff --git a/pkg/flowcli/config/json/deploy_test.go b/pkg/flowcli/config/json/deploy_test.go index 3075b930a..d7b5517f5 100644 --- a/pkg/flowcli/config/json/deploy_test.go +++ b/pkg/flowcli/config/json/deploy_test.go @@ -19,17 +19,27 @@ package json import ( "encoding/json" + "regexp" + "strings" "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/onflow/cadence" + + "github.com/stretchr/testify/assert" ) +func cleanSpecialChars(code []byte) string { + space := regexp.MustCompile(`\s+`) + return strings.ReplaceAll(space.ReplaceAllString(string(code), " "), " ", "") +} + func Test_ConfigDeploymentsSimple(t *testing.T) { b := []byte(`{ "testnet": { "account-1": ["FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"] - }, + }, "emulator": { "account-2": ["KittyItems", "KittyItemsMarket"], "account-3": ["FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"] @@ -61,24 +71,35 @@ func Test_ConfigDeploymentsSimple(t *testing.T) { assert.Equal(t, account2Name, account2Deployment[0].Account) assert.Equal(t, account3Name, account3Deployment[0].Account) - assert.Equal(t, - []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"}, - account1Deployment[0].Contracts, - ) + assert.Len(t, account1Deployment[0].Contracts, 4) + + for i, name := range []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"} { + assert.Equal(t, account1Deployment[0].Contracts[i].Name, name) + } + + for i, name := range []string{"KittyItems", "KittyItemsMarket"} { + assert.Equal(t, account2Deployment[0].Contracts[i].Name, name) + } - assert.Equal(t, - []string{"KittyItems", "KittyItemsMarket"}, - account2Deployment[0].Contracts, - ) + for i, name := range []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"} { + assert.Equal(t, account3Deployment[0].Contracts[i].Name, name) + } - assert.Equal(t, - []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"}, - account3Deployment[0].Contracts, - ) } func Test_TransformDeployToJSON(t *testing.T) { - b := []byte(`{"emulator":{"account-3":["KittyItems","KittyItemsMarket"],"account-4":["FungibleToken","NonFungibleToken","Kibble","KittyItems","KittyItemsMarket"]},"testnet":{"account-2":["FungibleToken","NonFungibleToken","Kibble","KittyItems"]}}`) + b := []byte(`{ + "emulator":{ + "account-3":["KittyItems", { + "name": "Kibble", + "args": [{ "type": "String", "value": "Hello World" }] + }], + "account-4":["FungibleToken","NonFungibleToken","Kibble","KittyItems","KittyItemsMarket"] + }, + "testnet":{ + "account-2":["FungibleToken","NonFungibleToken","Kibble","KittyItems"] + } + }`) var jsonDeployments jsonDeployments err := json.Unmarshal(b, &jsonDeployments) @@ -89,14 +110,14 @@ func Test_TransformDeployToJSON(t *testing.T) { j := transformDeploymentsToJSON(deployments) x, _ := json.Marshal(j) - assert.Equal(t, string(b), string(x)) + assert.Equal(t, cleanSpecialChars(b), cleanSpecialChars(x)) } func Test_DeploymentAdvanced(t *testing.T) { b := []byte(`{ "emulator": { "alice": [ - "KittyItems", { + { "name": "Kibble", "args": [{ "type": "String", "value": "Hello World" }] }, @@ -108,4 +129,14 @@ func Test_DeploymentAdvanced(t *testing.T) { var jsonDeployments jsonDeployments err := json.Unmarshal(b, &jsonDeployments) assert.NoError(t, err) + + deployments := jsonDeployments.transformToConfig() + + alice := deployments.GetByAccountAndNetwork("alice", "emulator") + assert.Len(t, alice, 1) + assert.Len(t, alice[0].Contracts, 2) + assert.Equal(t, alice[0].Contracts[0].Name, "Kibble") + assert.Equal(t, alice[0].Contracts[0].Args[0].Value, cadence.String("Hello World")) + assert.Equal(t, alice[0].Contracts[1].Name, "KittyItemsMarket") + assert.Len(t, alice[0].Contracts[1].Args, 0) } diff --git a/pkg/flowcli/project/project_test.go b/pkg/flowcli/project/project_test.go index a89af259c..98575ad8f 100644 --- a/pkg/flowcli/project/project_test.go +++ b/pkg/flowcli/project/project_test.go @@ -67,17 +67,31 @@ func generateComplexProject() Project { Network: "testnet", }}, Deployments: config.Deployments{{ - Network: "emulator", - Account: "emulator-account", - Contracts: []string{"KittyItems", "KittyItemsMarket"}, + Network: "emulator", + Account: "emulator-account", + Contracts: []config.ContractDeployment{ + {Name: "KittyItems", Args: nil}, + {Name: "KittyItemsMarket", Args: nil}, + }, }, { - Network: "emulator", - Account: "account-4", - Contracts: []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems", "KittyItemsMarket"}, + Network: "emulator", + Account: "account-4", + Contracts: []config.ContractDeployment{ + {Name: "FungibleToken", Args: nil}, + {Name: "NonFungibleToken", Args: nil}, + {Name: "Kibble", Args: nil}, + {Name: "KittyItems", Args: nil}, + {Name: "KittyItemsMarket", Args: nil}, + }, }, { - Network: "testnet", - Account: "account-2", - Contracts: []string{"FungibleToken", "NonFungibleToken", "Kibble", "KittyItems"}, + Network: "testnet", + Account: "account-2", + Contracts: []config.ContractDeployment{ + {Name: "FungibleToken", Args: nil}, + {Name: "NonFungibleToken", Args: nil}, + {Name: "Kibble", Args: nil}, + {Name: "KittyItems", Args: nil}, + }, }}, Accounts: config.Accounts{{ Name: "emulator-account", @@ -147,9 +161,11 @@ func generateSimpleProject() Project { Network: "emulator", }}, Deployments: config.Deployments{{ - Network: "emulator", - Account: "emulator-account", - Contracts: []string{"NonFungibleToken"}, + Network: "emulator", + Account: "emulator-account", + Contracts: []config.ContractDeployment{ + {Name: "NonFungibleToken", Args: nil}, + }, }}, Accounts: config.Accounts{{ Name: "emulator-account", @@ -198,9 +214,11 @@ func generateAliasesProject() Project { Alias: "ee82856bf20e2aa6", }}, Deployments: config.Deployments{{ - Network: "emulator", - Account: "emulator-account", - Contracts: []string{"NonFungibleToken"}, + Network: "emulator", + Account: "emulator-account", + Contracts: []config.ContractDeployment{ + {Name: "NonFungibleToken", Args: nil}, + }, }}, Accounts: config.Accounts{{ Name: "emulator-account", @@ -258,13 +276,18 @@ func generateAliasesComplexProject() Project { Alias: "ee82856bf20e2aa6", }}, Deployments: config.Deployments{{ - Network: "emulator", - Account: "emulator-account", - Contracts: []string{"NonFungibleToken"}, + Network: "emulator", + Account: "emulator-account", + Contracts: []config.ContractDeployment{ + {Name: "NonFungibleToken", Args: nil}, + }, }, { - Network: "testnet", - Account: "testnet-account", - Contracts: []string{"NonFungibleToken", "FungibleToken"}, + Network: "testnet", + Account: "testnet-account", + Contracts: []config.ContractDeployment{ + {Name: "NonFungibleToken", Args: nil}, + {Name: "FungibleToken", Args: nil}, + }, }}, Accounts: config.Accounts{{ Name: "emulator-account", From f1ebce85fa592f31d44b901fc945a063dae5cce0 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:10:57 +0200 Subject: [PATCH 013/171] added args to contracts --- pkg/flowcli/contracts/contracts.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/flowcli/contracts/contracts.go b/pkg/flowcli/contracts/contracts.go index 4325ea583..4b3d99752 100644 --- a/pkg/flowcli/contracts/contracts.go +++ b/pkg/flowcli/contracts/contracts.go @@ -24,6 +24,8 @@ import ( "path" "strings" + "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/cadence/runtime/ast" "github.com/onflow/cadence/runtime/common" "github.com/onflow/cadence/runtime/parser2" @@ -39,6 +41,7 @@ type Contract struct { source string target flow.Address code string + args []flowcli.CadenceArgument program *ast.Program dependencies map[string]*Contract aliases map[string]flow.Address @@ -50,6 +53,7 @@ func newContract( contractSource, contractCode string, target flow.Address, + args []flowcli.CadenceArgument, ) (*Contract, error) { program, err := parser2.ParseProgram(contractCode) if err != nil { @@ -63,6 +67,7 @@ func newContract( target: target, code: contractCode, program: program, + args: args, dependencies: make(map[string]*Contract), aliases: make(map[string]flow.Address), }, nil @@ -80,6 +85,10 @@ func (c *Contract) Code() string { return c.code } +func (c *Contract) Args() []flowcli.CadenceArgument { + return c.args +} + func (c *Contract) TranspiledCode() string { code := c.code @@ -177,6 +186,7 @@ func (p *Preprocessor) AddContractSource( contractName, contractSource string, target flow.Address, + args []flowcli.CadenceArgument, ) error { contractCode, err := p.loader.Load(contractSource) if err != nil { @@ -189,6 +199,7 @@ func (p *Preprocessor) AddContractSource( contractSource, contractCode, target, + args, ) if err != nil { return err From add8269cdfa79920312a2412d9382ac1d5d7af64 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:12:39 +0200 Subject: [PATCH 014/171] network cleanup --- pkg/flowcli/config/json/network.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/flowcli/config/json/network.go b/pkg/flowcli/config/json/network.go index 73d645e87..a16920c78 100644 --- a/pkg/flowcli/config/json/network.go +++ b/pkg/flowcli/config/json/network.go @@ -66,7 +66,7 @@ func transformNetworksToJSON(networks config.Networks) jsonNetworks { } } else { // if advanced case jsonNetworks[n.Name] = jsonNetwork{ - Advanced: advanced{ + Advanced: advancedNetwork{ Host: n.Host, ChainID: n.ChainID.String(), }, @@ -77,14 +77,14 @@ func transformNetworksToJSON(networks config.Networks) jsonNetworks { return jsonNetworks } -type advanced struct { +type advancedNetwork struct { Host string `json:"host"` ChainID string `json:"chain"` } type jsonNetwork struct { Host string - Advanced advanced + Advanced advancedNetwork } func (j *jsonNetwork) UnmarshalJSON(b []byte) error { @@ -97,7 +97,7 @@ func (j *jsonNetwork) UnmarshalJSON(b []byte) error { } // advanced - var advanced advanced + var advanced advancedNetwork err = json.Unmarshal(b, &advanced) if err == nil { j.Advanced = advanced From 9a4859b67787e8f0c9bd089148a8145777208bce Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:12:51 +0200 Subject: [PATCH 015/171] json parsing deployment with args --- pkg/flowcli/config/json/deploy.go | 106 +++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 32 deletions(-) diff --git a/pkg/flowcli/config/json/deploy.go b/pkg/flowcli/config/json/deploy.go index c21d4aa24..b11fcdbc6 100644 --- a/pkg/flowcli/config/json/deploy.go +++ b/pkg/flowcli/config/json/deploy.go @@ -22,24 +22,46 @@ import ( "encoding/json" "github.com/onflow/flow-cli/pkg/flowcli" - "github.com/onflow/flow-cli/pkg/flowcli/config" ) -type jsonDeployments map[string]jsonDeploy +type jsonDeployments map[string]jsonDeployment // transformToConfig transforms json structures to config structure func (j jsonDeployments) transformToConfig() config.Deployments { deployments := make(config.Deployments, 0) - for networkName, d := range j { - for accountName, contracts := range d.Simple { - deploy := config.Deploy{ - Network: networkName, - Account: accountName, - Contracts: contracts, + for networkName, deploys := range j { + + var deploy config.Deploy + for accountName, contracts := range deploys { + deploy = config.Deploy{ + Network: networkName, + Account: accountName, } + var contractDeploys []config.ContractDeployment + for _, contract := range contracts { + if contract.simple != "" { + contractDeploys = append( + contractDeploys, + config.ContractDeployment{ + Name: contract.simple, + Args: nil, + }, + ) + } else { + contractDeploys = append( + contractDeploys, + config.ContractDeployment{ + Name: contract.advanced.Name, + Args: contract.advanced.Args, + }, + ) + } + } + + deploy.Contracts = contractDeploys deployments = append(deployments, deploy) } } @@ -48,51 +70,67 @@ func (j jsonDeployments) transformToConfig() config.Deployments { } // transformToJSON transforms config structure to json structures for saving -func transformDeploymentsToJSON(deployments config.Deployments) jsonDeployments { - jsonDeployments := jsonDeployments{} +func transformDeploymentsToJSON(configDeployments config.Deployments) jsonDeployments { + jsonDeploys := jsonDeployments{} + + for _, d := range configDeployments { + + deployments := make([]deployment, 0) + for _, c := range d.Contracts { + if len(c.Args) == 0 { + deployments = append(deployments, deployment{ + simple: c.Name, + }) + } else { + deployments = append(deployments, deployment{ + advanced: contractDeployment{ + Name: c.Name, + Args: c.Args, + }, + }) + } + } - for _, d := range deployments { - if _, exists := jsonDeployments[d.Network]; exists { - jsonDeployments[d.Network].Simple[d.Account] = d.Contracts + if _, ok := jsonDeploys[d.Network]; ok { + jsonDeploys[d.Network][d.Account] = deployments } else { - jsonDeployments[d.Network] = jsonDeploy{ - Simple: map[string][]string{ - d.Account: d.Contracts, - }, + jsonDeploys[d.Network] = jsonDeployment{ + d.Account: deployments, } } + } - return jsonDeployments + return jsonDeploys } -type advanced struct { - name string - args []flowcli.CadenceArgument +type contractDeployment struct { + Name string `json:"name"` + Args []flowcli.CadenceArgument `json:"args"` } type deployment struct { simple string - advanced advanced + advanced contractDeployment } -type jsonDeploy map[string][]deployment +type jsonDeployment map[string][]deployment -func (j *jsonDeploy) UnmarshalJSON(b []byte) error { - var simple Simple - var advanced advancedArgs +func (d *deployment) UnmarshalJSON(b []byte) error { - // simple + // simple format + var simple string err := json.Unmarshal(b, &simple) if err == nil { - j.Simple = simple + d.simple = simple return nil } - // advanced + // advanced format + var advanced contractDeployment err = json.Unmarshal(b, &advanced) if err == nil { - j.AdvancedArgs = advanced + d.advanced = advanced } else { return err } @@ -100,6 +138,10 @@ func (j *jsonDeploy) UnmarshalJSON(b []byte) error { return nil } -func (j jsonDeploy) MarshalJSON() ([]byte, error) { - return json.Marshal(j.Simple) +func (d deployment) MarshalJSON() ([]byte, error) { + if d.simple != "" { + return json.Marshal(d.simple) + } else { + return json.Marshal(d.advanced) + } } From eb6c1149b4b748d1c1c323adbbfd61baeaf1928a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:13:03 +0200 Subject: [PATCH 016/171] adding deployment args to project --- pkg/flowcli/project/project.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 711fcfbf7..c39598dcb 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -23,6 +23,8 @@ import ( "fmt" "path" + "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/afero" @@ -50,6 +52,7 @@ type Contract struct { Name string Source string Target flow.Address + Args []flowcli.CadenceArgument } // Load loads a project configuration and returns the resulting project. @@ -201,13 +204,14 @@ func (p *Project) ContractsByNetwork(network string) []Contract { account := p.AccountByName(deploy.Account) // go through each contract in this deployment - for _, contractName := range deploy.Contracts { - c := p.conf.Contracts.GetByNameAndNetwork(contractName, network) + for _, deploymentContract := range deploy.Contracts { + c := p.conf.Contracts.GetByNameAndNetwork(deploymentContract.Name, network) contract := Contract{ Name: c.Name, Source: path.Clean(c.Source), Target: account.address, + Args: deploymentContract.Args, } contracts = append(contracts, contract) From e467337cf18472f0ac19586c392f745816bc5edd Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 8 Apr 2021 17:13:22 +0200 Subject: [PATCH 017/171] wip deployment --- pkg/flowcli/services/project.go | 39 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index dbef62ae8..3b329c620 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -22,6 +22,9 @@ import ( "fmt" "strings" + "github.com/onflow/cadence" + jsoncdc "github.com/onflow/cadence/encoding/json" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/onflow/flow-go-sdk/templates" @@ -117,6 +120,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er contract.Name, contract.Source, contract.Target, + contract.Args, ) if err != nil { return nil, err @@ -128,19 +132,19 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er return nil, err } - contracts, err := processor.ContractDeploymentOrder() + orderedContracts, err := processor.ContractDeploymentOrder() if err != nil { return nil, err } p.logger.Info(fmt.Sprintf( "Deploying %d contracts for accounts: %s", - len(contracts), + len(orderedContracts), strings.Join(p.project.AllAccountName(), ","), )) var errs []error - for _, contract := range contracts { + for _, contract := range orderedContracts { targetAccount := p.project.AccountByAddress(contract.Target().String()) if targetAccount == nil { @@ -166,9 +170,14 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er tx = prepareUpdateContractTransaction(targetAccount.Address(), contract) } else { - tx = prepareAddContractTransaction(targetAccount.Address(), contract) + //tx = prepareAddContractTransaction(targetAccount.Address(), contract) } + tx = addAccountContractWithArgs(targetAccount.Address(), templates.Contract{ + Name: contract.Name(), + Source: contract.TranspiledCode(), + }, contract.Args()[0].Value) + tx, err = p.gateway.SendTransaction(tx, targetAccount) if err != nil { p.logger.Error(err.Error()) @@ -208,7 +217,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er return nil, fmt.Errorf(`%v`, errs) } - return contracts, nil + return orderedContracts, nil } func prepareUpdateContractTransaction( @@ -236,3 +245,23 @@ func prepareAddContractTransaction( }, ) } + +const addAccountContractTemplate = ` +transaction(name: String, code: String, supply: UFix64) { + prepare(signer: AuthAccount) { + signer.contracts.add(name: name, code: code.decodeHex(), supply: supply) + } +} +` + +func addAccountContractWithArgs(address flow.Address, contract templates.Contract, supply cadence.Value) *flow.Transaction { + cadenceName := cadence.NewString(contract.Name) + cadenceCode := cadence.NewString(contract.SourceHex()) + + return flow.NewTransaction(). + SetScript([]byte(addAccountContractTemplate)). + AddRawArgument(jsoncdc.MustEncode(cadenceName)). + AddRawArgument(jsoncdc.MustEncode(cadenceCode)). + AddRawArgument(jsoncdc.MustEncode(supply)). + AddAuthorizer(address) +} From 153c169e73cd7d93ba5411558c7c16f065da06a0 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 18:52:51 +0300 Subject: [PATCH 018/171] Pass project to status service --- pkg/flowcli/services/services.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/services/services.go b/pkg/flowcli/services/services.go index 40fa22155..d2271ec2d 100644 --- a/pkg/flowcli/services/services.go +++ b/pkg/flowcli/services/services.go @@ -54,6 +54,6 @@ func NewServices( Collections: NewCollections(gateway, proj, logger), Project: NewProject(gateway, proj, logger), Blocks: NewBlocks(gateway, proj, logger), - Status: NewStatus(gateway, logger), + Status: NewStatus(gateway, proj, logger), } } From 28ca64431c8af0925dd9b72635b8a6d3b9e5d8b6 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 18:53:34 +0300 Subject: [PATCH 019/171] Move logic to status service --- internal/status/status.go | 84 ++-------------------------------- pkg/flowcli/services/status.go | 83 +++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 84 deletions(-) diff --git a/internal/status/status.go b/internal/status/status.go index 5cb550458..ac125236b 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -19,14 +19,9 @@ package status import ( - "bytes" - "fmt" - "github.com/fatih/color" "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" "github.com/spf13/cobra" - "text/tabwriter" ) type FlagsStatus struct { @@ -34,21 +29,6 @@ type FlagsStatus struct { var statusFlags = FlagsStatus{} -// Result structure -type Result struct { - network string - accessNode string - connectionError error -} - -const ( - OnlineIcon = "🟢" - OnlineStatus = "ONLINE" - - OfflineIcon = "🔴" - OfflineStatus = "OFFLINE" -) - var InitCommand = &command.Command{ Cmd: &cobra.Command{ Use: "status", @@ -67,65 +47,7 @@ var InitCommand = &command.Command{ network = "emulator" } - proj, err := project.Load(globalFlags.ConfigPath) - - if err != nil { - return nil, fmt.Errorf("project can't be loaded from specified config path") - } - - accessNode := proj.NetworkByName(network).Host - - err = services.Status.Ping() - return &Result{ - network, - accessNode, - err, - }, nil + response := services.Status.Ping(network) + return &response, nil }, -} - -func (r *Result) String() string { - var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) - - fmt.Fprintf(writer, "Status:\t %s %s\n", r.GetStatusIcon(), r.GetStatus()) - fmt.Fprintf(writer, "Network:\t %s\n", r.network) - fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) - - writer.Flush() - return b.String() -} - -// JSON convert result to JSON -func (r *Result) JSON() interface{} { - result := make(map[string]string) - - result["network"] = r.network - result["accessNode"] = r.accessNode - result["status"] = r.GetStatus() - - return result -} - -// Oneliner show result as one liner grep friendly -func (r *Result) Oneliner() string { - return fmt.Sprintf("%s:%s", r.network, r.GetStatus()) -} - -// GetStatus returns string representation for network status -func (r *Result) GetStatus() string { - if r.connectionError == nil { - return color.GreenString("%s", OnlineStatus) - } - - return color.RedString("%s", OfflineStatus) -} - -// GetStatusIcon returns emoji icon representing network status -func (r *Result) GetStatusIcon() string { - if r.connectionError == nil { - return OnlineIcon - } - - return OfflineIcon -} +} \ No newline at end of file diff --git a/pkg/flowcli/services/status.go b/pkg/flowcli/services/status.go index 1000810b2..04ea165db 100644 --- a/pkg/flowcli/services/status.go +++ b/pkg/flowcli/services/status.go @@ -19,28 +19,105 @@ package services import ( + "bytes" + "fmt" + "github.com/fatih/color" "github.com/onflow/flow-cli/pkg/flowcli/gateway" "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "text/tabwriter" +) + + +const ( + OnlineIcon = "🟢" + OnlineStatus = "ONLINE" + + OfflineIcon = "🔴" + OfflineStatus = "OFFLINE" ) // Status is a service that handles status of access node type Status struct { gateway gateway.Gateway + project *project.Project logger output.Logger } -// NewPing returns a new ping service +// NewStatus returns a new ping service func NewStatus( gateway gateway.Gateway, + project *project.Project, logger output.Logger, ) *Status { return &Status{ gateway: gateway, + project: project, logger: logger, } } -func (e *Status) Ping() error { - return e.gateway.Ping() +// Ping sends Ping request to network +func (s *Status) Ping(network string) PingResponse { + err := s.gateway.Ping() + accessNode := s.project.NetworkByName(network).Host + + return PingResponse{ + network: network, + accessNode: accessNode, + connectionError: err, + } +} + +type PingResponse struct { + network string + accessNode string + connectionError error +} + +// GetStatus returns string representation for network status +func (r *PingResponse) getStatus() string { + if r.connectionError == nil { + return color.GreenString("%s", OnlineStatus) + } + + return color.RedString("%s", OfflineStatus) +} + +// GetStatusIcon returns emoji icon representing network status +func (r *PingResponse) getStatusIcon() string { + if r.connectionError == nil { + return OnlineIcon + } + + return OfflineIcon +} + +func (r *PingResponse) String() string { + var b bytes.Buffer + writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + + fmt.Fprintf(writer, "Status:\t %s %s\n", r.getStatusIcon(), r.getStatus()) + fmt.Fprintf(writer, "Network:\t %s\n", r.network) + fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) + + writer.Flush() + return b.String() +} + +// JSON convert result to JSON +func (r *PingResponse) JSON() interface{} { + result := make(map[string]string) + + result["network"] = r.network + result["accessNode"] = r.accessNode + result["status"] = r.getStatus() + + return result +} + +// Oneliner show result as one liner grep friendly +func (r *PingResponse) Oneliner() string { + return fmt.Sprintf("%s:%s", r.network, r.getStatus()) } From 44a5bdaffe27a678581efbd0a236cafaf8197d09 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 18:59:55 +0300 Subject: [PATCH 020/171] Add missing global flags --- docs/get-status.md | 57 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/get-status.md b/docs/get-status.md index 3c10976f0..48753141e 100644 --- a/docs/get-status.md +++ b/docs/get-status.md @@ -18,13 +18,66 @@ Network: testnet Access Node: access.devnet.nodes.onflow.org:9000 ``` -## Options +## Flags ### Network - Flag: `--network` - Short Flag: `-n` -- Valid inputs: the name of a network defined in the configuration (`flow.json`) +- Valid inputs: the name of a network defined in the configuration (`flow.json`). Specify which network you want the command to use for execution. +### Host + +- Flag: `--host` +- Valid inputs: an IP address or hostname. +- Default: `127.0.0.1:3569` (Flow Emulator) + +Specify the hostname of the Access API that will be +used to execute the command. This flag overrides +any host defined by the `--network` flag. + +### Filter + +- Flag: `--filter` +- Short Flag: `-x` +- Valid inputs: a case-sensitive name of the result property. + +Specify any property name from the result you want to return as the only value. + +### Output + +- Flag: `--output` +- Short Flag: `-o` +- Valid inputs: `json`, `inline` + +Specify the format of the command results. + +### Save + +- Flag: `--save` +- Short Flag: `-s` +- Valid inputs: a path in the current filesystem. + +Specify the filename where you want the result to be saved + +### Log + +- Flag: `--log` +- Short Flag: `-l` +- Valid inputs: `none`, `error`, `debug` +- Default: `info` + +Specify the log level. Control how much output you want to see during command execution. + +### Configuration + +- Flag: `--conf` +- Short Flag: `-f` +- Valid inputs: a path in the current filesystem. +- Default: `flow.json` + +Specify the path to the `flow.json` configuration file. +You can use the `-f` flag multiple times to merge +several configuration files. From f370e6f51309fe883d114163e0ebb0a019a9fd43 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 19:12:01 +0300 Subject: [PATCH 021/171] Use util colors --- pkg/flowcli/services/status.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/flowcli/services/status.go b/pkg/flowcli/services/status.go index 04ea165db..9c718d79e 100644 --- a/pkg/flowcli/services/status.go +++ b/pkg/flowcli/services/status.go @@ -21,10 +21,10 @@ package services import ( "bytes" "fmt" - "github.com/fatih/color" "github.com/onflow/flow-cli/pkg/flowcli/gateway" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/util" "text/tabwriter" ) @@ -78,10 +78,10 @@ type PingResponse struct { // GetStatus returns string representation for network status func (r *PingResponse) getStatus() string { if r.connectionError == nil { - return color.GreenString("%s", OnlineStatus) + return util.Green(OnlineStatus) } - return color.RedString("%s", OfflineStatus) + return util.Red(OfflineStatus) } // GetStatusIcon returns emoji icon representing network status From 6c9ee22f4469d7a4c28a4c0501a0ce02651a5cb7 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 16:18:22 +0300 Subject: [PATCH 022/171] Add CreateTabWriter factory method --- internal/command/result.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/internal/command/result.go b/internal/command/result.go index 994e7d462..2882e762c 100644 --- a/internal/command/result.go +++ b/internal/command/result.go @@ -18,8 +18,17 @@ package command +import ( + "bytes" + "text/tabwriter" +) + type Result interface { String() string Oneliner() string JSON() interface{} } + +func CreateTabWriter(b *bytes.Buffer) *tabwriter.Writer { + return tabwriter.NewWriter(b, 0, 8, 1, '\t', tabwriter.AlignRight) +} \ No newline at end of file From a0201e71bef30c3e8bd666ce6958b35e11b27649 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 16:19:08 +0300 Subject: [PATCH 023/171] Refactor code with CreateTabWriter --- internal/accounts/accounts.go | 5 ++--- internal/accounts/staking-info.go | 4 +--- internal/blocks/blocks.go | 5 ++--- internal/collections/collections.go | 7 +++---- internal/config/init.go | 4 +--- internal/events/events.go | 7 +++---- internal/keys/keys.go | 5 ++--- internal/scripts/scripts.go | 5 ++--- internal/transactions/transactions.go | 5 ++--- 9 files changed, 18 insertions(+), 29 deletions(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index 2ff688c42..c9858134d 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -21,9 +21,8 @@ package accounts import ( "bytes" "fmt" - "text/tabwriter" - "github.com/onflow/cadence" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" ) @@ -83,7 +82,7 @@ func (r *AccountResult) JSON() interface{} { // String convert result to string func (r *AccountResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Address\t 0x%s\n", r.Address) fmt.Fprintf(writer, "Balance\t %s\n", cadence.UFix64(r.Balance)) diff --git a/internal/accounts/staking-info.go b/internal/accounts/staking-info.go index 88e008788..3949d2abf 100644 --- a/internal/accounts/staking-info.go +++ b/internal/accounts/staking-info.go @@ -21,8 +21,6 @@ package accounts import ( "bytes" "fmt" - "text/tabwriter" - "github.com/onflow/cadence" "github.com/spf13/cobra" @@ -75,7 +73,7 @@ func (r *StakingResult) JSON() interface{} { // String convert result to string func (r *StakingResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Account Staking Info:\n") diff --git a/internal/blocks/blocks.go b/internal/blocks/blocks.go index 9e90aa58c..15f5e1de2 100644 --- a/internal/blocks/blocks.go +++ b/internal/blocks/blocks.go @@ -21,8 +21,7 @@ package blocks import ( "bytes" "fmt" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" @@ -80,7 +79,7 @@ func (r *BlockResult) JSON() interface{} { // String convert result to string func (r *BlockResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Block ID\t%s\n", r.block.ID) fmt.Fprintf(writer, "Parent ID\t%s\n", r.block.ParentID) diff --git a/internal/collections/collections.go b/internal/collections/collections.go index f18b4ec4e..9e55bb77a 100644 --- a/internal/collections/collections.go +++ b/internal/collections/collections.go @@ -21,11 +21,10 @@ package collections import ( "bytes" "fmt" - "strings" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" + "strings" ) var Cmd = &cobra.Command{ @@ -57,7 +56,7 @@ func (c *CollectionResult) JSON() interface{} { // String convert result to string func (c *CollectionResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Collection ID %s:\n", c.Collection.ID()) diff --git a/internal/config/init.go b/internal/config/init.go index 5571ecdf6..5c1fe10b8 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -21,8 +21,6 @@ package config import ( "bytes" "fmt" - "text/tabwriter" - "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" @@ -79,7 +77,7 @@ func (r *InitResult) JSON() interface{} { // String convert result to string func (r *InitResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) account, _ := r.Project.EmulatorServiceAccount() fmt.Fprintf(writer, "Configuration initialized\n") diff --git a/internal/events/events.go b/internal/events/events.go index 30373388d..1a5f85f6e 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -21,13 +21,12 @@ package events import ( "bytes" "fmt" - "io" - "text/tabwriter" - "github.com/onflow/cadence" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" + "io" "github.com/onflow/flow-cli/pkg/flowcli/util" ) @@ -68,7 +67,7 @@ func (k *EventResult) JSON() interface{} { // String convert result to string func (k *EventResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) for _, blockEvent := range k.BlockEvents { if len(blockEvent.Events) > 0 { diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 8c271934c..37837b151 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -22,8 +22,7 @@ import ( "bytes" "encoding/hex" "fmt" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" @@ -58,7 +57,7 @@ func (k *KeyResult) JSON() interface{} { // String convert result to string func (k *KeyResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) if k.privateKey != nil { fmt.Fprintf(writer, "🔴️ Store private key safely and don't share with anyone! \n") diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index a9190d419..05516f131 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -21,9 +21,8 @@ package scripts import ( "bytes" "fmt" - "text/tabwriter" - "github.com/onflow/cadence" + "github.com/onflow/flow-cli/internal/command" "github.com/spf13/cobra" ) @@ -51,7 +50,7 @@ func (r *ScriptResult) JSON() interface{} { // String convert result to string func (r *ScriptResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Result: %s\n", r.Value) diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index e2a9ae2bb..2bcc2f5ac 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -21,8 +21,7 @@ package transactions import ( "bytes" "fmt" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" @@ -63,7 +62,7 @@ func (r *TransactionResult) JSON() interface{} { // String convert result to string func (r *TransactionResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "ID\t %s\n", r.tx.ID()) fmt.Fprintf(writer, "Status\t %s\n", r.result.Status) From f73163dde5dd10d51d9c6e10fa74ce313eef2595 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 19:09:38 +0300 Subject: [PATCH 024/171] Move CreateTabWriter to util It was impossible to import command package from service --- internal/command/result.go | 9 --------- pkg/flowcli/util/utilities.go | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/internal/command/result.go b/internal/command/result.go index 2882e762c..af0b5e4f4 100644 --- a/internal/command/result.go +++ b/internal/command/result.go @@ -18,17 +18,8 @@ package command -import ( - "bytes" - "text/tabwriter" -) - type Result interface { String() string Oneliner() string JSON() interface{} -} - -func CreateTabWriter(b *bytes.Buffer) *tabwriter.Writer { - return tabwriter.NewWriter(b, 0, 8, 1, '\t', tabwriter.AlignRight) } \ No newline at end of file diff --git a/pkg/flowcli/util/utilities.go b/pkg/flowcli/util/utilities.go index da14ec420..bfce4b795 100644 --- a/pkg/flowcli/util/utilities.go +++ b/pkg/flowcli/util/utilities.go @@ -19,8 +19,10 @@ package util import ( + "bytes" "fmt" "io/ioutil" + "text/tabwriter" "github.com/fatih/color" @@ -104,3 +106,7 @@ func GetAddressNetwork(address flow.Address) (flow.ChainID, error) { return "", fmt.Errorf("address not valid for any known chain: %s", address) } + +func CreateTabWriter(b *bytes.Buffer) *tabwriter.Writer { + return tabwriter.NewWriter(b, 0, 8, 1, '\t', tabwriter.AlignRight) +} From a4a3053140f2e38ccef96c33ffc623cb75c2cfd1 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 19:10:02 +0300 Subject: [PATCH 025/171] Use util package instead of command --- internal/accounts/accounts.go | 4 ++-- internal/accounts/staking-info.go | 3 ++- internal/blocks/blocks.go | 4 ++-- internal/collections/collections.go | 4 ++-- internal/config/init.go | 2 +- internal/events/events.go | 3 +-- internal/keys/keys.go | 4 ++-- internal/scripts/scripts.go | 4 ++-- internal/transactions/transactions.go | 4 ++-- pkg/flowcli/services/status.go | 3 +-- 10 files changed, 17 insertions(+), 18 deletions(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index c9858134d..4a95b07b7 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -22,7 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" ) @@ -82,7 +82,7 @@ func (r *AccountResult) JSON() interface{} { // String convert result to string func (r *AccountResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Address\t 0x%s\n", r.Address) fmt.Fprintf(writer, "Balance\t %s\n", cadence.UFix64(r.Balance)) diff --git a/internal/accounts/staking-info.go b/internal/accounts/staking-info.go index 3949d2abf..1b9aaa917 100644 --- a/internal/accounts/staking-info.go +++ b/internal/accounts/staking-info.go @@ -22,6 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" @@ -73,7 +74,7 @@ func (r *StakingResult) JSON() interface{} { // String convert result to string func (r *StakingResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Account Staking Info:\n") diff --git a/internal/blocks/blocks.go b/internal/blocks/blocks.go index 15f5e1de2..22b008f33 100644 --- a/internal/blocks/blocks.go +++ b/internal/blocks/blocks.go @@ -21,7 +21,7 @@ package blocks import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" @@ -79,7 +79,7 @@ func (r *BlockResult) JSON() interface{} { // String convert result to string func (r *BlockResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Block ID\t%s\n", r.block.ID) fmt.Fprintf(writer, "Parent ID\t%s\n", r.block.ParentID) diff --git a/internal/collections/collections.go b/internal/collections/collections.go index 9e55bb77a..1c3694c2c 100644 --- a/internal/collections/collections.go +++ b/internal/collections/collections.go @@ -21,7 +21,7 @@ package collections import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" "strings" @@ -56,7 +56,7 @@ func (c *CollectionResult) JSON() interface{} { // String convert result to string func (c *CollectionResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Collection ID %s:\n", c.Collection.ID()) diff --git a/internal/config/init.go b/internal/config/init.go index 5c1fe10b8..e982f7c74 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -77,7 +77,7 @@ func (r *InitResult) JSON() interface{} { // String convert result to string func (r *InitResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) account, _ := r.Project.EmulatorServiceAccount() fmt.Fprintf(writer, "Configuration initialized\n") diff --git a/internal/events/events.go b/internal/events/events.go index 1a5f85f6e..a72a4f009 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -22,7 +22,6 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" @@ -67,7 +66,7 @@ func (k *EventResult) JSON() interface{} { // String convert result to string func (k *EventResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) for _, blockEvent := range k.BlockEvents { if len(blockEvent.Events) > 0 { diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 37837b151..bc2d7988f 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -22,7 +22,7 @@ import ( "bytes" "encoding/hex" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" @@ -57,7 +57,7 @@ func (k *KeyResult) JSON() interface{} { // String convert result to string func (k *KeyResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) if k.privateKey != nil { fmt.Fprintf(writer, "🔴️ Store private key safely and don't share with anyone! \n") diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index 05516f131..db817a9f7 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -22,7 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" ) @@ -50,7 +50,7 @@ func (r *ScriptResult) JSON() interface{} { // String convert result to string func (r *ScriptResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Result: %s\n", r.Value) diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 2bcc2f5ac..f72e47f4f 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -21,7 +21,7 @@ package transactions import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" @@ -62,7 +62,7 @@ func (r *TransactionResult) JSON() interface{} { // String convert result to string func (r *TransactionResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "ID\t %s\n", r.tx.ID()) fmt.Fprintf(writer, "Status\t %s\n", r.result.Status) diff --git a/pkg/flowcli/services/status.go b/pkg/flowcli/services/status.go index 9c718d79e..db8bd1788 100644 --- a/pkg/flowcli/services/status.go +++ b/pkg/flowcli/services/status.go @@ -25,7 +25,6 @@ import ( "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/util" - "text/tabwriter" ) @@ -95,7 +94,7 @@ func (r *PingResponse) getStatusIcon() string { func (r *PingResponse) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Status:\t %s %s\n", r.getStatusIcon(), r.getStatus()) fmt.Fprintf(writer, "Network:\t %s\n", r.network) From c6af8bdfd049f12aa44388e55bd2c9aa374f9115 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Fri, 9 Apr 2021 16:03:47 +0300 Subject: [PATCH 026/171] Refactor service and command according to review comments --- internal/status/status.go | 87 ++++++++++++++++++++++++++++++++-- pkg/flowcli/services/status.go | 76 ++--------------------------- 2 files changed, 87 insertions(+), 76 deletions(-) diff --git a/internal/status/status.go b/internal/status/status.go index ac125236b..03ec23ea0 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -19,9 +19,13 @@ package status import ( + "bytes" + "fmt" "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" + "text/tabwriter" ) type FlagsStatus struct { @@ -29,6 +33,49 @@ type FlagsStatus struct { var statusFlags = FlagsStatus{} + +type Result struct { + network string + accessNode string + connectionError error +} + + +const ( + OnlineIcon = "🟢" + OnlineStatus = "ONLINE" + + OfflineIcon = "🔴" + OfflineStatus = "OFFLINE" +) + +// getStatus returns string representation for network status +func (r *Result) getStatus() string { + if r.connectionError == nil { + return OnlineStatus + } + + return OfflineStatus +} + +// getColoredStatus returns colored string representation for network status +func (r *Result) getColoredStatus() string { + if r.connectionError == nil { + return util.Green(OnlineStatus) + } + + return util.Red(OfflineStatus) +} + +// getIcon returns emoji icon representing network statu +func (r *Result) getIcon() string { + if r.connectionError == nil { + return OnlineIcon + } + + return OfflineIcon +} + var InitCommand = &command.Command{ Cmd: &cobra.Command{ Use: "status", @@ -47,7 +94,41 @@ var InitCommand = &command.Command{ network = "emulator" } - response := services.Status.Ping(network) - return &response, nil + accessNode, err := services.Status.Ping(network) + + return &Result{ + network: network, + accessNode: accessNode, + connectionError: err, + }, nil }, -} \ No newline at end of file +} + +// String convert result to string +func (r *Result) String() string { + var b bytes.Buffer + writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + + fmt.Fprintf(writer, "Status:\t %s %s\n", r.getIcon(), r.getColoredStatus()) + fmt.Fprintf(writer, "Network:\t %s\n", r.network) + fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) + + writer.Flush() + return b.String() +} + +// JSON convert result to JSON +func (r *Result) JSON() interface{} { + result := make(map[string]string) + + result["network"] = r.network + result["accessNode"] = r.accessNode + result["status"] = r.getStatus() + + return result +} + +// Oneliner show result as one liner grep friendly +func (r *Result) Oneliner() string { + return r.getStatus() +} diff --git a/pkg/flowcli/services/status.go b/pkg/flowcli/services/status.go index 9c718d79e..fd5bd9f2f 100644 --- a/pkg/flowcli/services/status.go +++ b/pkg/flowcli/services/status.go @@ -19,22 +19,9 @@ package services import ( - "bytes" - "fmt" "github.com/onflow/flow-cli/pkg/flowcli/gateway" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" - "github.com/onflow/flow-cli/pkg/flowcli/util" - "text/tabwriter" -) - - -const ( - OnlineIcon = "🟢" - OnlineStatus = "ONLINE" - - OfflineIcon = "🔴" - OfflineStatus = "OFFLINE" ) // Status is a service that handles status of access node @@ -58,66 +45,9 @@ func NewStatus( } // Ping sends Ping request to network -func (s *Status) Ping(network string) PingResponse { +func (s *Status) Ping(network string) (string, error) { err := s.gateway.Ping() accessNode := s.project.NetworkByName(network).Host - return PingResponse{ - network: network, - accessNode: accessNode, - connectionError: err, - } -} - -type PingResponse struct { - network string - accessNode string - connectionError error -} - -// GetStatus returns string representation for network status -func (r *PingResponse) getStatus() string { - if r.connectionError == nil { - return util.Green(OnlineStatus) - } - - return util.Red(OfflineStatus) -} - -// GetStatusIcon returns emoji icon representing network status -func (r *PingResponse) getStatusIcon() string { - if r.connectionError == nil { - return OnlineIcon - } - - return OfflineIcon -} - -func (r *PingResponse) String() string { - var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) - - fmt.Fprintf(writer, "Status:\t %s %s\n", r.getStatusIcon(), r.getStatus()) - fmt.Fprintf(writer, "Network:\t %s\n", r.network) - fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) - - writer.Flush() - return b.String() -} - -// JSON convert result to JSON -func (r *PingResponse) JSON() interface{} { - result := make(map[string]string) - - result["network"] = r.network - result["accessNode"] = r.accessNode - result["status"] = r.getStatus() - - return result -} - -// Oneliner show result as one liner grep friendly -func (r *PingResponse) Oneliner() string { - return fmt.Sprintf("%s:%s", r.network, r.getStatus()) -} - + return accessNode, err +} \ No newline at end of file From 1fcda7fe22ce77f4d456be06b5d4781b268120b5 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 16:18:22 +0300 Subject: [PATCH 027/171] Add CreateTabWriter factory method --- internal/command/result.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/internal/command/result.go b/internal/command/result.go index 994e7d462..2882e762c 100644 --- a/internal/command/result.go +++ b/internal/command/result.go @@ -18,8 +18,17 @@ package command +import ( + "bytes" + "text/tabwriter" +) + type Result interface { String() string Oneliner() string JSON() interface{} } + +func CreateTabWriter(b *bytes.Buffer) *tabwriter.Writer { + return tabwriter.NewWriter(b, 0, 8, 1, '\t', tabwriter.AlignRight) +} \ No newline at end of file From 940f13088b1337bbd80a52f37d3c5b49b37be3d0 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 16:19:08 +0300 Subject: [PATCH 028/171] Refactor code with CreateTabWriter --- internal/accounts/accounts.go | 5 ++--- internal/accounts/staking-info.go | 4 +--- internal/blocks/blocks.go | 5 ++--- internal/collections/collections.go | 7 +++---- internal/config/init.go | 4 +--- internal/events/events.go | 7 +++---- internal/keys/keys.go | 5 ++--- internal/scripts/scripts.go | 5 ++--- internal/transactions/transactions.go | 5 ++--- 9 files changed, 18 insertions(+), 29 deletions(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index 2ff688c42..c9858134d 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -21,9 +21,8 @@ package accounts import ( "bytes" "fmt" - "text/tabwriter" - "github.com/onflow/cadence" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" ) @@ -83,7 +82,7 @@ func (r *AccountResult) JSON() interface{} { // String convert result to string func (r *AccountResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Address\t 0x%s\n", r.Address) fmt.Fprintf(writer, "Balance\t %s\n", cadence.UFix64(r.Balance)) diff --git a/internal/accounts/staking-info.go b/internal/accounts/staking-info.go index 88e008788..3949d2abf 100644 --- a/internal/accounts/staking-info.go +++ b/internal/accounts/staking-info.go @@ -21,8 +21,6 @@ package accounts import ( "bytes" "fmt" - "text/tabwriter" - "github.com/onflow/cadence" "github.com/spf13/cobra" @@ -75,7 +73,7 @@ func (r *StakingResult) JSON() interface{} { // String convert result to string func (r *StakingResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Account Staking Info:\n") diff --git a/internal/blocks/blocks.go b/internal/blocks/blocks.go index 9e90aa58c..15f5e1de2 100644 --- a/internal/blocks/blocks.go +++ b/internal/blocks/blocks.go @@ -21,8 +21,7 @@ package blocks import ( "bytes" "fmt" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" @@ -80,7 +79,7 @@ func (r *BlockResult) JSON() interface{} { // String convert result to string func (r *BlockResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Block ID\t%s\n", r.block.ID) fmt.Fprintf(writer, "Parent ID\t%s\n", r.block.ParentID) diff --git a/internal/collections/collections.go b/internal/collections/collections.go index f18b4ec4e..9e55bb77a 100644 --- a/internal/collections/collections.go +++ b/internal/collections/collections.go @@ -21,11 +21,10 @@ package collections import ( "bytes" "fmt" - "strings" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" + "strings" ) var Cmd = &cobra.Command{ @@ -57,7 +56,7 @@ func (c *CollectionResult) JSON() interface{} { // String convert result to string func (c *CollectionResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Collection ID %s:\n", c.Collection.ID()) diff --git a/internal/config/init.go b/internal/config/init.go index 5571ecdf6..5c1fe10b8 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -21,8 +21,6 @@ package config import ( "bytes" "fmt" - "text/tabwriter" - "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" @@ -79,7 +77,7 @@ func (r *InitResult) JSON() interface{} { // String convert result to string func (r *InitResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) account, _ := r.Project.EmulatorServiceAccount() fmt.Fprintf(writer, "Configuration initialized\n") diff --git a/internal/events/events.go b/internal/events/events.go index 30373388d..1a5f85f6e 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -21,13 +21,12 @@ package events import ( "bytes" "fmt" - "io" - "text/tabwriter" - "github.com/onflow/cadence" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" + "io" "github.com/onflow/flow-cli/pkg/flowcli/util" ) @@ -68,7 +67,7 @@ func (k *EventResult) JSON() interface{} { // String convert result to string func (k *EventResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) for _, blockEvent := range k.BlockEvents { if len(blockEvent.Events) > 0 { diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 8c271934c..37837b151 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -22,8 +22,7 @@ import ( "bytes" "encoding/hex" "fmt" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" @@ -58,7 +57,7 @@ func (k *KeyResult) JSON() interface{} { // String convert result to string func (k *KeyResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) if k.privateKey != nil { fmt.Fprintf(writer, "🔴️ Store private key safely and don't share with anyone! \n") diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index a9190d419..05516f131 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -21,9 +21,8 @@ package scripts import ( "bytes" "fmt" - "text/tabwriter" - "github.com/onflow/cadence" + "github.com/onflow/flow-cli/internal/command" "github.com/spf13/cobra" ) @@ -51,7 +50,7 @@ func (r *ScriptResult) JSON() interface{} { // String convert result to string func (r *ScriptResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "Result: %s\n", r.Value) diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index e2a9ae2bb..2bcc2f5ac 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -21,8 +21,7 @@ package transactions import ( "bytes" "fmt" - "text/tabwriter" - + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" @@ -63,7 +62,7 @@ func (r *TransactionResult) JSON() interface{} { // String convert result to string func (r *TransactionResult) String() string { var b bytes.Buffer - writer := tabwriter.NewWriter(&b, 0, 8, 1, '\t', tabwriter.AlignRight) + writer := command.CreateTabWriter(&b) fmt.Fprintf(writer, "ID\t %s\n", r.tx.ID()) fmt.Fprintf(writer, "Status\t %s\n", r.result.Status) From 016cf68c7d42e23e56f73badc9a9641624cb5301 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 19:09:38 +0300 Subject: [PATCH 029/171] Move CreateTabWriter to util It was impossible to import command package from service --- internal/command/result.go | 9 --------- pkg/flowcli/util/utilities.go | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/internal/command/result.go b/internal/command/result.go index 2882e762c..af0b5e4f4 100644 --- a/internal/command/result.go +++ b/internal/command/result.go @@ -18,17 +18,8 @@ package command -import ( - "bytes" - "text/tabwriter" -) - type Result interface { String() string Oneliner() string JSON() interface{} -} - -func CreateTabWriter(b *bytes.Buffer) *tabwriter.Writer { - return tabwriter.NewWriter(b, 0, 8, 1, '\t', tabwriter.AlignRight) } \ No newline at end of file diff --git a/pkg/flowcli/util/utilities.go b/pkg/flowcli/util/utilities.go index da14ec420..bfce4b795 100644 --- a/pkg/flowcli/util/utilities.go +++ b/pkg/flowcli/util/utilities.go @@ -19,8 +19,10 @@ package util import ( + "bytes" "fmt" "io/ioutil" + "text/tabwriter" "github.com/fatih/color" @@ -104,3 +106,7 @@ func GetAddressNetwork(address flow.Address) (flow.ChainID, error) { return "", fmt.Errorf("address not valid for any known chain: %s", address) } + +func CreateTabWriter(b *bytes.Buffer) *tabwriter.Writer { + return tabwriter.NewWriter(b, 0, 8, 1, '\t', tabwriter.AlignRight) +} From 3d5c2a23651f626847bc3594f2b138c0fbff3136 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 8 Apr 2021 19:10:02 +0300 Subject: [PATCH 030/171] Use util package instead of command --- internal/accounts/accounts.go | 4 ++-- internal/accounts/staking-info.go | 3 ++- internal/blocks/blocks.go | 4 ++-- internal/collections/collections.go | 4 ++-- internal/config/init.go | 2 +- internal/events/events.go | 3 +-- internal/keys/keys.go | 4 ++-- internal/scripts/scripts.go | 4 ++-- internal/transactions/transactions.go | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index c9858134d..4a95b07b7 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -22,7 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" ) @@ -82,7 +82,7 @@ func (r *AccountResult) JSON() interface{} { // String convert result to string func (r *AccountResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Address\t 0x%s\n", r.Address) fmt.Fprintf(writer, "Balance\t %s\n", cadence.UFix64(r.Balance)) diff --git a/internal/accounts/staking-info.go b/internal/accounts/staking-info.go index 3949d2abf..1b9aaa917 100644 --- a/internal/accounts/staking-info.go +++ b/internal/accounts/staking-info.go @@ -22,6 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" @@ -73,7 +74,7 @@ func (r *StakingResult) JSON() interface{} { // String convert result to string func (r *StakingResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Account Staking Info:\n") diff --git a/internal/blocks/blocks.go b/internal/blocks/blocks.go index 15f5e1de2..22b008f33 100644 --- a/internal/blocks/blocks.go +++ b/internal/blocks/blocks.go @@ -21,7 +21,7 @@ package blocks import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" @@ -79,7 +79,7 @@ func (r *BlockResult) JSON() interface{} { // String convert result to string func (r *BlockResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Block ID\t%s\n", r.block.ID) fmt.Fprintf(writer, "Parent ID\t%s\n", r.block.ParentID) diff --git a/internal/collections/collections.go b/internal/collections/collections.go index 9e55bb77a..1c3694c2c 100644 --- a/internal/collections/collections.go +++ b/internal/collections/collections.go @@ -21,7 +21,7 @@ package collections import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" "strings" @@ -56,7 +56,7 @@ func (c *CollectionResult) JSON() interface{} { // String convert result to string func (c *CollectionResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Collection ID %s:\n", c.Collection.ID()) diff --git a/internal/config/init.go b/internal/config/init.go index 5c1fe10b8..e982f7c74 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -77,7 +77,7 @@ func (r *InitResult) JSON() interface{} { // String convert result to string func (r *InitResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) account, _ := r.Project.EmulatorServiceAccount() fmt.Fprintf(writer, "Configuration initialized\n") diff --git a/internal/events/events.go b/internal/events/events.go index 1a5f85f6e..a72a4f009 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -22,7 +22,6 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" @@ -67,7 +66,7 @@ func (k *EventResult) JSON() interface{} { // String convert result to string func (k *EventResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) for _, blockEvent := range k.BlockEvents { if len(blockEvent.Events) > 0 { diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 37837b151..bc2d7988f 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -22,7 +22,7 @@ import ( "bytes" "encoding/hex" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" @@ -57,7 +57,7 @@ func (k *KeyResult) JSON() interface{} { // String convert result to string func (k *KeyResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) if k.privateKey != nil { fmt.Fprintf(writer, "🔴️ Store private key safely and don't share with anyone! \n") diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index 05516f131..db817a9f7 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -22,7 +22,7 @@ import ( "bytes" "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" ) @@ -50,7 +50,7 @@ func (r *ScriptResult) JSON() interface{} { // String convert result to string func (r *ScriptResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "Result: %s\n", r.Value) diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 2bcc2f5ac..f72e47f4f 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -21,7 +21,7 @@ package transactions import ( "bytes" "fmt" - "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" @@ -62,7 +62,7 @@ func (r *TransactionResult) JSON() interface{} { // String convert result to string func (r *TransactionResult) String() string { var b bytes.Buffer - writer := command.CreateTabWriter(&b) + writer := util.CreateTabWriter(&b) fmt.Fprintf(writer, "ID\t %s\n", r.tx.ID()) fmt.Fprintf(writer, "Status\t %s\n", r.result.Status) From 76b21617bb35dd231d70546b9b30e90b96a1b48e Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 9 Apr 2021 19:30:40 +0200 Subject: [PATCH 031/171] adding name to deploy --- pkg/flowcli/config/config.go | 10 ++++++-- pkg/flowcli/config/json/deploy.go | 33 ++++++++++++++++++++++---- pkg/flowcli/config/json/deploy_test.go | 17 +++++++++---- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 9963c61e8..185da917e 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -21,7 +21,7 @@ package config import ( "errors" - "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/cadence" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" @@ -58,7 +58,13 @@ type Deploy struct { // ContractDeployment defines the deployment of the contract with possible args type ContractDeployment struct { Name string - Args []flowcli.CadenceArgument + Args []ContractArgument +} + +// ContractArgument defines contract init argument by name, type and value +type ContractArgument struct { + Name string + Arg cadence.Value } // Contract defines the configuration for a Cadence contract. diff --git a/pkg/flowcli/config/json/deploy.go b/pkg/flowcli/config/json/deploy.go index b11fcdbc6..57bc47206 100644 --- a/pkg/flowcli/config/json/deploy.go +++ b/pkg/flowcli/config/json/deploy.go @@ -21,7 +21,8 @@ package json import ( "encoding/json" - "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/cadence" + "github.com/onflow/flow-cli/pkg/flowcli/config" ) @@ -51,11 +52,20 @@ func (j jsonDeployments) transformToConfig() config.Deployments { }, ) } else { + args := make([]config.ContractArgument, 0) + for _, arg := range contract.advanced.Args { + + args = append(args, config.ContractArgument{ + Name: arg.Name, + Arg: arg.Arg, + }) + } + contractDeploys = append( contractDeploys, config.ContractDeployment{ Name: contract.advanced.Name, - Args: contract.advanced.Args, + Args: args, }, ) } @@ -82,10 +92,18 @@ func transformDeploymentsToJSON(configDeployments config.Deployments) jsonDeploy simple: c.Name, }) } else { + args := make([]argument, 0) + for _, arg := range c.Args { + args = append(args, argument{ + Name: arg.Name, + Arg: arg.Arg, + }) + } + deployments = append(deployments, deployment{ advanced: contractDeployment{ Name: c.Name, - Args: c.Args, + Args: args, }, }) } @@ -104,9 +122,14 @@ func transformDeploymentsToJSON(configDeployments config.Deployments) jsonDeploy return jsonDeploys } +type argument struct { + Name string + Arg cadence.Value +} + type contractDeployment struct { - Name string `json:"name"` - Args []flowcli.CadenceArgument `json:"args"` + Name string `json:"name"` + Args []argument `json:"args"` } type deployment struct { diff --git a/pkg/flowcli/config/json/deploy_test.go b/pkg/flowcli/config/json/deploy_test.go index d7b5517f5..0f1fb6c2f 100644 --- a/pkg/flowcli/config/json/deploy_test.go +++ b/pkg/flowcli/config/json/deploy_test.go @@ -19,13 +19,14 @@ package json import ( "encoding/json" + "fmt" "regexp" "strings" "testing" - "github.com/stretchr/testify/require" + jsoncdc "github.com/onflow/cadence/encoding/json" - "github.com/onflow/cadence" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/assert" ) @@ -119,7 +120,7 @@ func Test_DeploymentAdvanced(t *testing.T) { "alice": [ { "name": "Kibble", - "args": [{ "type": "String", "value": "Hello World" }] + "args": [{ "name": "foo", "type": "String", "value": "Hello World" }] }, "KittyItemsMarket" ] @@ -136,7 +137,15 @@ func Test_DeploymentAdvanced(t *testing.T) { assert.Len(t, alice, 1) assert.Len(t, alice[0].Contracts, 2) assert.Equal(t, alice[0].Contracts[0].Name, "Kibble") - assert.Equal(t, alice[0].Contracts[0].Args[0].Value, cadence.String("Hello World")) + assert.Equal(t, alice[0].Contracts[0].Args[0].Arg.String(), "Hello World") + assert.Equal(t, alice[0].Contracts[0].Args[0].Name, "foo") assert.Equal(t, alice[0].Contracts[1].Name, "KittyItemsMarket") assert.Len(t, alice[0].Contracts[1].Args, 0) } + +func Test_Decode(t *testing.T) { + b := []byte(`{ "name": "foo", "type": "String", "value": "Hello World" }`) + val, err := jsoncdc.Decode(b) + assert.NoError(t, err) + fmt.Println(val) +} From ab383495fc711120a4cd8264782ef05ee2c60b3f Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 12 Apr 2021 15:40:47 +0200 Subject: [PATCH 032/171] change type deploy --- pkg/flowcli/contracts/contracts.go | 10 +++++----- pkg/flowcli/project/project.go | 4 +--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/pkg/flowcli/contracts/contracts.go b/pkg/flowcli/contracts/contracts.go index 4b3d99752..fc4c02d02 100644 --- a/pkg/flowcli/contracts/contracts.go +++ b/pkg/flowcli/contracts/contracts.go @@ -24,7 +24,7 @@ import ( "path" "strings" - "github.com/onflow/flow-cli/pkg/flowcli" + "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/cadence/runtime/ast" "github.com/onflow/cadence/runtime/common" @@ -41,7 +41,7 @@ type Contract struct { source string target flow.Address code string - args []flowcli.CadenceArgument + args []config.ContractArgument program *ast.Program dependencies map[string]*Contract aliases map[string]flow.Address @@ -53,7 +53,7 @@ func newContract( contractSource, contractCode string, target flow.Address, - args []flowcli.CadenceArgument, + args []config.ContractArgument, ) (*Contract, error) { program, err := parser2.ParseProgram(contractCode) if err != nil { @@ -85,7 +85,7 @@ func (c *Contract) Code() string { return c.code } -func (c *Contract) Args() []flowcli.CadenceArgument { +func (c *Contract) Args() []config.ContractArgument { return c.args } @@ -186,7 +186,7 @@ func (p *Preprocessor) AddContractSource( contractName, contractSource string, target flow.Address, - args []flowcli.CadenceArgument, + args []config.ContractArgument, ) error { contractCode, err := p.loader.Load(contractSource) if err != nil { diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index c39598dcb..99516d4fa 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -23,8 +23,6 @@ import ( "fmt" "path" - "github.com/onflow/flow-cli/pkg/flowcli" - "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/afero" @@ -52,7 +50,7 @@ type Contract struct { Name string Source string Target flow.Address - Args []flowcli.CadenceArgument + Args []config.ContractArgument } // Load loads a project configuration and returns the resulting project. From 46119446728059184b585cc9ec8d80389d98affc Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 12 Apr 2021 17:00:01 +0200 Subject: [PATCH 033/171] implement name arg --- pkg/flowcli/config/json/deploy.go | 31 ++++++++++++++------------ pkg/flowcli/config/json/deploy_test.go | 25 ++++++++++----------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/pkg/flowcli/config/json/deploy.go b/pkg/flowcli/config/json/deploy.go index 57bc47206..f1eb1dfab 100644 --- a/pkg/flowcli/config/json/deploy.go +++ b/pkg/flowcli/config/json/deploy.go @@ -20,8 +20,9 @@ package json import ( "encoding/json" + "fmt" - "github.com/onflow/cadence" + jsoncdc "github.com/onflow/cadence/encoding/json" "github.com/onflow/flow-cli/pkg/flowcli/config" ) @@ -54,10 +55,16 @@ func (j jsonDeployments) transformToConfig() config.Deployments { } else { args := make([]config.ContractArgument, 0) for _, arg := range contract.advanced.Args { + name := arg["name"] + delete(arg, "name") + + // todo check if parser exists for better solution + b, _ := json.Marshal(arg) + cadenceArg, _ := jsoncdc.Decode(b) args = append(args, config.ContractArgument{ - Name: arg.Name, - Arg: arg.Arg, + Name: name, + Arg: cadenceArg, }) } @@ -92,11 +99,12 @@ func transformDeploymentsToJSON(configDeployments config.Deployments) jsonDeploy simple: c.Name, }) } else { - args := make([]argument, 0) + args := make([]map[string]string, 0) for _, arg := range c.Args { - args = append(args, argument{ - Name: arg.Name, - Arg: arg.Arg, + args = append(args, map[string]string{ + "name": arg.Name, + "type": arg.Arg.Type().ID(), + "value": fmt.Sprintf("%v", arg.Arg.ToGoValue()), }) } @@ -122,14 +130,9 @@ func transformDeploymentsToJSON(configDeployments config.Deployments) jsonDeploy return jsonDeploys } -type argument struct { - Name string - Arg cadence.Value -} - type contractDeployment struct { - Name string `json:"name"` - Args []argument `json:"args"` + Name string `json:"name"` + Args []map[string]string `json:"args"` } type deployment struct { diff --git a/pkg/flowcli/config/json/deploy_test.go b/pkg/flowcli/config/json/deploy_test.go index 0f1fb6c2f..c6fec82a9 100644 --- a/pkg/flowcli/config/json/deploy_test.go +++ b/pkg/flowcli/config/json/deploy_test.go @@ -19,13 +19,10 @@ package json import ( "encoding/json" - "fmt" "regexp" "strings" "testing" - jsoncdc "github.com/onflow/cadence/encoding/json" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/assert" @@ -93,7 +90,10 @@ func Test_TransformDeployToJSON(t *testing.T) { "emulator":{ "account-3":["KittyItems", { "name": "Kibble", - "args": [{ "type": "String", "value": "Hello World" }] + "args": [ + { "name": "foo", "type": "String", "value": "Hello World" }, + { "name": "bar", "type": "Int8", "value": "10" } + ] }], "account-4":["FungibleToken","NonFungibleToken","Kibble","KittyItems","KittyItemsMarket"] }, @@ -120,7 +120,10 @@ func Test_DeploymentAdvanced(t *testing.T) { "alice": [ { "name": "Kibble", - "args": [{ "name": "foo", "type": "String", "value": "Hello World" }] + "args": [ + { "name": "foo", "type": "String", "value": "Hello World" }, + { "name": "bar", "type": "Int8", "value": "10" } + ] }, "KittyItemsMarket" ] @@ -137,15 +140,11 @@ func Test_DeploymentAdvanced(t *testing.T) { assert.Len(t, alice, 1) assert.Len(t, alice[0].Contracts, 2) assert.Equal(t, alice[0].Contracts[0].Name, "Kibble") - assert.Equal(t, alice[0].Contracts[0].Args[0].Arg.String(), "Hello World") + assert.Len(t, alice[0].Contracts[0].Args, 2) assert.Equal(t, alice[0].Contracts[0].Args[0].Name, "foo") + assert.Equal(t, alice[0].Contracts[0].Args[0].Arg.String(), `"Hello World"`) + assert.Equal(t, alice[0].Contracts[0].Args[1].Name, "bar") + assert.Equal(t, alice[0].Contracts[0].Args[1].Arg.String(), "10") assert.Equal(t, alice[0].Contracts[1].Name, "KittyItemsMarket") assert.Len(t, alice[0].Contracts[1].Args, 0) } - -func Test_Decode(t *testing.T) { - b := []byte(`{ "name": "foo", "type": "String", "value": "Hello World" }`) - val, err := jsoncdc.Decode(b) - assert.NoError(t, err) - fmt.Println(val) -} From 445b73c941f984f3d102628057294887da6ff7ad Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 12 Apr 2021 17:00:15 +0200 Subject: [PATCH 034/171] add contract to tx --- pkg/flowcli/services/project.go | 56 +++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 3b329c620..1af83b22c 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -22,6 +22,8 @@ import ( "fmt" "strings" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/cadence" jsoncdc "github.com/onflow/cadence/encoding/json" @@ -161,23 +163,31 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er _, exists := targetAccountInfo.Contracts[contract.Name()] if exists { if !update { - p.logger.Error(fmt.Sprintf( - "Contract %s is already deployed to this account. Use the --update flag to force update.", + err = fmt.Errorf( + "contract %s is already deployed to this account. Use the --update flag to force update", + contract.Name(), + ) + p.logger.Error(err.Error()) + errs = append(errs, err) + continue + } else if len(contract.Args()) > 0 { // todo discuss we might better remove the contract and redeploy it - ux issue + err = fmt.Errorf( + "contract %s is already deployed and can not be updated with initialization arguments", contract.Name(), - )) + ) + p.logger.Error(err.Error()) + errs = append(errs, err) continue } tx = prepareUpdateContractTransaction(targetAccount.Address(), contract) } else { - //tx = prepareAddContractTransaction(targetAccount.Address(), contract) + tx = addAccountContractWithArgs(targetAccount.Address(), templates.Contract{ + Name: contract.Name(), + Source: contract.TranspiledCode(), + }, contract.Args()) } - tx = addAccountContractWithArgs(targetAccount.Address(), templates.Contract{ - Name: contract.Name(), - Source: contract.TranspiledCode(), - }, contract.Args()[0].Value) - tx, err = p.gateway.SendTransaction(tx, targetAccount) if err != nil { p.logger.Error(err.Error()) @@ -247,21 +257,35 @@ func prepareAddContractTransaction( } const addAccountContractTemplate = ` -transaction(name: String, code: String, supply: UFix64) { +transaction(name: String, code: String%s) { prepare(signer: AuthAccount) { - signer.contracts.add(name: name, code: code.decodeHex(), supply: supply) + signer.contracts.add(name: name, code: code.decodeHex()%s) } } ` -func addAccountContractWithArgs(address flow.Address, contract templates.Contract, supply cadence.Value) *flow.Transaction { +func addAccountContractWithArgs( + address flow.Address, + contract templates.Contract, + args []config.ContractArgument, +) *flow.Transaction { cadenceName := cadence.NewString(contract.Name) cadenceCode := cadence.NewString(contract.SourceHex()) - return flow.NewTransaction(). - SetScript([]byte(addAccountContractTemplate)). + tx := flow.NewTransaction(). AddRawArgument(jsoncdc.MustEncode(cadenceName)). - AddRawArgument(jsoncdc.MustEncode(cadenceCode)). - AddRawArgument(jsoncdc.MustEncode(supply)). + AddRawArgument(jsoncdc.MustEncode(cadenceCode)) + + txArgs, addArgs := "", "" + for _, arg := range args { + tx.AddRawArgument(jsoncdc.MustEncode(arg.Arg)) + txArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Arg.Type().ID()) + addArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Name) + } + + script := fmt.Sprintf(addAccountContractTemplate, txArgs, addArgs) + + return tx. + SetScript([]byte(script)). AddAuthorizer(address) } From c2f35ec526973be27be3053925ddfba01c2fd9e7 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 12 Apr 2021 17:37:38 +0200 Subject: [PATCH 035/171] conflict resolve --- pkg/flowcli/project/transaction.go | 49 ++++++++++++++-- pkg/flowcli/services/accounts.go | 1 + pkg/flowcli/services/project.go | 92 ++++++++++-------------------- 3 files changed, 74 insertions(+), 68 deletions(-) diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index aac7802e0..dcec3fc5a 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -7,6 +7,10 @@ import ( "io/ioutil" "strings" + jsoncdc "github.com/onflow/cadence/encoding/json" + + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-go-sdk/templates" "github.com/onflow/flow-cli/pkg/flowcli" @@ -80,14 +84,18 @@ func NewUpdateAccountContractTransaction(signer *Account, name string, source st return tx, nil } -func NewAddAccountContractTransaction(signer *Account, name string, source string) (*Transaction, error) { - contract := templates.Contract{ - Name: name, - Source: source, - } +func NewAddAccountContractTransaction( + signer *Account, + name string, + source string, + args []config.ContractArgument, +) (*Transaction, error) { tx := &Transaction{ - tx: templates.AddAccountContract(signer.Address(), contract), + tx: addAccountContractWithArgs(templates.Contract{ + Name: name, + Source: source, + }, args), } err := tx.SetSigner(signer) @@ -112,6 +120,35 @@ func NewRemoveAccountContractTransaction(signer *Account, name string) (*Transac return tx, nil } +func addAccountContractWithArgs( + contract templates.Contract, + args []config.ContractArgument, +) *flow.Transaction { + const addAccountContractTemplate = ` + transaction(name: String, code: String%s) { + prepare(signer: AuthAccount) { + signer.contracts.add(name: name, code: code.decodeHex()%s) + } + }` + + cadenceName := cadence.NewString(contract.Name) + cadenceCode := cadence.NewString(contract.SourceHex()) + + tx := flow.NewTransaction(). + AddRawArgument(jsoncdc.MustEncode(cadenceName)). + AddRawArgument(jsoncdc.MustEncode(cadenceCode)) + + txArgs, addArgs := "", "" + for _, arg := range args { + tx.AddRawArgument(jsoncdc.MustEncode(arg.Arg)) + txArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Arg.Type().ID()) + addArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Name) + } + + script := fmt.Sprintf(addAccountContractTemplate, txArgs, addArgs) + return tx.SetScript([]byte(script)) +} + func NewCreateAccountTransaction( signer *Account, keys []*flow.AccountKey, diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index da76b852a..13c70bf5c 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -361,6 +361,7 @@ func (a *Accounts) addContract( account, contractName, string(contractSource), + []config.ContractArgument{}, // todo add support for args on account add-contract ) if err != nil { return nil, err diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 1a24e05ab..ccc99cfad 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -22,9 +22,7 @@ import ( "fmt" "strings" - "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" - "github.com/onflow/flow-go-sdk/templates" "github.com/onflow/flow-cli/pkg/flowcli/contracts" "github.com/onflow/flow-cli/pkg/flowcli/gateway" @@ -99,18 +97,19 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er } // check there are not multiple accounts with same contract - // TODO: specify which contract by name is a problem if p.project.ContractConflictExists(network) { - return nil, fmt.Errorf( + return nil, fmt.Errorf( // TODO: specify which contract by name is a problem "the same contract cannot be deployed to multiple accounts on the same network", ) } + // create new processor for contract processor := contracts.NewPreprocessor( contracts.FilesystemLoader{}, p.project.AliasesForNetwork(network), ) + // add all contracts needed to deploy to processor for _, contract := range p.project.ContractsByNetwork(network) { err := processor.AddContractSource( contract.Name, @@ -123,11 +122,13 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er } } + // resolve imports assigns accounts to imports err := processor.ResolveImports() if err != nil { return nil, err } + // sort correct deployment order of contracts so we don't have import that is not yet deployed orderedContracts, err := processor.ContractDeploymentOrder() if err != nil { return nil, err @@ -139,6 +140,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er strings.Join(p.project.AccountNamesForNetwork(network), ","), )) + // go through each contract and deploy it deployErr := false for _, contract := range orderedContracts { targetAccount := p.project.AccountByAddress(contract.Target().String()) @@ -147,43 +149,43 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er return nil, fmt.Errorf("target account for deploying contract not found in configuration") } + // get deployment account targetAccountInfo, err := p.gateway.GetAccount(targetAccount.Address()) if err != nil { return nil, fmt.Errorf("failed to fetch information for account %s with error %s", targetAccount.Address(), err.Error()) } - tx, err := project.NewAddAccountContractTransaction(targetAccount, contract.Name(), contract.TranspiledCode()) + // create transaction to deploy new contract with args + tx, err := project.NewAddAccountContractTransaction( + targetAccount, + contract.Name(), + contract.TranspiledCode(), + contract.Args(), + ) if err != nil { return nil, err } - + // check if contract exists on account _, exists := targetAccountInfo.Contracts[contract.Name()] - if exists { - if !update { - p.logger.Error(fmt.Sprintf( - "contract %s is already deployed to this account. Use the --update flag to force update", - contract.Name(), - ) - deployErr = true - continue - } else if len(contract.Args()) > 0 { // todo discuss we might better remove the contract and redeploy it - ux issue - p.logger.Error(fmt.Sprintf( - "contract %s is already deployed and can not be updated with initialization arguments", - contract.Name(), - )) - deployErr = true - continue - } - + if exists && !update { + p.logger.Error(fmt.Sprintf( + "contract %s is already deployed to this account. Use the --update flag to force update", + contract.Name(), + )) + deployErr = true + continue + } else if exists && len(contract.Args()) > 0 { // todo discuss we might better remove the contract and redeploy it - ux issue + p.logger.Error(fmt.Sprintf( + "contract %s is already deployed and can not be updated with initialization arguments", + contract.Name(), + )) + deployErr = true + continue + } else if exists { tx, err = project.NewUpdateAccountContractTransaction(targetAccount, contract.Name(), contract.TranspiledCode()) if err != nil { return nil, err } - } else { - tx = addAccountContractWithArgs(targetAccount.Address(), templates.Contract{ - Name: contract.Name(), - Source: contract.TranspiledCode(), - }, contract.Args()) } sentTx, err := p.gateway.SendTransaction(tx) @@ -223,37 +225,3 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er return orderedContracts, nil } - -const addAccountContractTemplate = ` -transaction(name: String, code: String%s) { - prepare(signer: AuthAccount) { - signer.contracts.add(name: name, code: code.decodeHex()%s) - } -} -` - -func addAccountContractWithArgs( - address flow.Address, - contract templates.Contract, - args []config.ContractArgument, -) *flow.Transaction { - cadenceName := cadence.NewString(contract.Name) - cadenceCode := cadence.NewString(contract.SourceHex()) - - tx := flow.NewTransaction(). - AddRawArgument(jsoncdc.MustEncode(cadenceName)). - AddRawArgument(jsoncdc.MustEncode(cadenceCode)) - - txArgs, addArgs := "", "" - for _, arg := range args { - tx.AddRawArgument(jsoncdc.MustEncode(arg.Arg)) - txArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Arg.Type().ID()) - addArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Name) - } - - script := fmt.Sprintf(addAccountContractTemplate, txArgs, addArgs) - - return tx. - SetScript([]byte(script)). - AddAuthorizer(address) -} From 111acf48f8ad7f00e9d020cf91064d1a31b3b713 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 12 Apr 2021 17:48:45 +0200 Subject: [PATCH 036/171] tests and lints --- pkg/flowcli/config/config_test.go | 10 ++++------ pkg/flowcli/contracts/contracts_test.go | 4 ++++ pkg/flowcli/services/accounts_test.go | 1 - 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pkg/flowcli/config/config_test.go b/pkg/flowcli/config/config_test.go index df586edff..ddfcf68c7 100644 --- a/pkg/flowcli/config/config_test.go +++ b/pkg/flowcli/config/config_test.go @@ -20,8 +20,6 @@ package config_test import ( "testing" - "github.com/onflow/flow-cli/pkg/flowcli" - "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/stretchr/testify/assert" @@ -173,10 +171,10 @@ func Test_GetDeploymentsByNetworkComplex(t *testing.T) { deployments := conf.Deployments.GetByAccountAndNetwork("account-2", "testnet") assert.Equal(t, deployments[0].Contracts, []config.ContractDeployment{ - {Name: "FungibleToken", Args: []flowcli.CadenceArgument(nil)}, - {Name: "NonFungibleToken", Args: []flowcli.CadenceArgument(nil)}, - {Name: "Kibble", Args: []flowcli.CadenceArgument(nil)}, - {Name: "KittyItems", Args: []flowcli.CadenceArgument(nil)}, + {Name: "FungibleToken", Args: []config.ContractArgument(nil)}, + {Name: "NonFungibleToken", Args: []config.ContractArgument(nil)}, + {Name: "Kibble", Args: []config.ContractArgument(nil)}, + {Name: "KittyItems", Args: []config.ContractArgument(nil)}, }) } diff --git a/pkg/flowcli/contracts/contracts_test.go b/pkg/flowcli/contracts/contracts_test.go index 9f6ed6d15..ea8a0039f 100644 --- a/pkg/flowcli/contracts/contracts_test.go +++ b/pkg/flowcli/contracts/contracts_test.go @@ -23,6 +23,8 @@ import ( "strings" "testing" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/test" "github.com/stretchr/testify/assert" @@ -228,6 +230,7 @@ func TestResolveImports(t *testing.T) { contract.name, contract.source, contract.target, + []config.ContractArgument{}, ) assert.NoError(t, err) } @@ -276,6 +279,7 @@ func TestContractDeploymentOrder(t *testing.T) { contract.name, contract.source, contract.target, + []config.ContractArgument{}, ) assert.NoError(t, err) } diff --git a/pkg/flowcli/services/accounts_test.go b/pkg/flowcli/services/accounts_test.go index 406a7eb4e..d6dffda5b 100644 --- a/pkg/flowcli/services/accounts_test.go +++ b/pkg/flowcli/services/accounts_test.go @@ -116,7 +116,6 @@ func TestAccounts(t *testing.T) { t.Run("Contract Add for Account", func(t *testing.T) { mock.SendTransactionMock = func(tx *project.Transaction) (*flow.Transaction, error) { - assert.Equal(t, tx.FlowTransaction().Authorizers[0].String(), serviceAddress) assert.Equal(t, tx.Signer().Address().String(), serviceAddress) assert.True(t, strings.Contains(string(tx.FlowTransaction().Script), "signer.contracts.add")) From 3ca29d243116eeba6f34c26fcf2a6aa5bc17b985 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 12 Apr 2021 18:41:03 +0200 Subject: [PATCH 037/171] headers missing --- internal/transactions/sign.go | 18 ++++++++++++++++++ pkg/flowcli/output/prompt.go | 18 ++++++++++++++++++ pkg/flowcli/project/transaction.go | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/internal/transactions/sign.go b/internal/transactions/sign.go index 9f926ee98..351384fe4 100644 --- a/internal/transactions/sign.go +++ b/internal/transactions/sign.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 transactions import ( diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index 34089ff89..efe94623e 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 output import ( diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index dcec3fc5a..c7d600ac5 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 project import ( From 14ad8e88d5c83e0b227e062810cd25d5c19b759c Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 14 Apr 2021 17:44:43 +0300 Subject: [PATCH 038/171] Remove unnecessary parenthesis --- pkg/flowcli/gateway/gateway.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/gateway/gateway.go b/pkg/flowcli/gateway/gateway.go index 598a25514..870ad3dfe 100644 --- a/pkg/flowcli/gateway/gateway.go +++ b/pkg/flowcli/gateway/gateway.go @@ -37,5 +37,5 @@ type Gateway interface { GetBlockByID(flow.Identifier) (*flow.Block, error) GetEvents(string, uint64, uint64) ([]client.BlockEvents, error) GetCollection(flow.Identifier) (*flow.Collection, error) - Ping() (error) + Ping() error } From 61096654ffdd78fe6736733c65d07308cfa91ee9 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Wed, 14 Apr 2021 17:44:56 +0300 Subject: [PATCH 039/171] Update MockGateway with Ping method --- tests/mockGateway.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/mockGateway.go b/tests/mockGateway.go index 0a4a08be7..861171390 100644 --- a/tests/mockGateway.go +++ b/tests/mockGateway.go @@ -38,6 +38,7 @@ type MockGateway struct { GetCollectionMock func(id flow.Identifier) (*flow.Collection, error) GetBlockByHeightMock func(uint64) (*flow.Block, error) GetBlockByIDMock func(flow.Identifier) (*flow.Block, error) + PingMock func() error } func NewMockGateway() gateway.Gateway { @@ -83,3 +84,7 @@ func (g *MockGateway) GetEvents(name string, start uint64, end uint64) ([]client func (g *MockGateway) GetCollection(id flow.Identifier) (*flow.Collection, error) { return g.GetCollectionMock(id) } + +func (g *MockGateway) Ping() error { + return nil +} From b5b983e7c8c63f1bbdce86e6a5488cbe6f4b4cbb Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 15 Apr 2021 14:55:46 +0300 Subject: [PATCH 040/171] Add newline at the end of the file. Add periods at the end of descriptions --- pkg/flowcli/services/status.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/flowcli/services/status.go b/pkg/flowcli/services/status.go index fd5bd9f2f..b97399122 100644 --- a/pkg/flowcli/services/status.go +++ b/pkg/flowcli/services/status.go @@ -24,14 +24,14 @@ import ( "github.com/onflow/flow-cli/pkg/flowcli/project" ) -// Status is a service that handles status of access node +// Status is a service that handles status of access node. type Status struct { gateway gateway.Gateway project *project.Project logger output.Logger } -// NewStatus returns a new ping service +// NewStatus returns a new status service. func NewStatus( gateway gateway.Gateway, project *project.Project, @@ -44,10 +44,10 @@ func NewStatus( } } -// Ping sends Ping request to network +// Ping sends Ping request to network. func (s *Status) Ping(network string) (string, error) { err := s.gateway.Ping() accessNode := s.project.NetworkByName(network).Host return accessNode, err -} \ No newline at end of file +} From e1862c2a286de31d8a6a7d63ec290185db7c552f Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 15 Apr 2021 14:56:38 +0300 Subject: [PATCH 041/171] Add newline at the end of the file --- internal/command/result.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/command/result.go b/internal/command/result.go index af0b5e4f4..994e7d462 100644 --- a/internal/command/result.go +++ b/internal/command/result.go @@ -22,4 +22,4 @@ type Result interface { String() string Oneliner() string JSON() interface{} -} \ No newline at end of file +} From 96a2b7df02f9d6e3a711b5dfffbc628898bc27e6 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 15 Apr 2021 14:57:03 +0300 Subject: [PATCH 042/171] Capture name of emulator network --- internal/command/command.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/command/command.go b/internal/command/command.go index 29c4ae78a..6db2166f3 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -61,6 +61,8 @@ type GlobalFlags struct { ConfigPath []string } +const NetworkEmulator = "emulator" + const ( formatText = "text" formatInline = "inline" From 508d675714c8d9d7d3e19ce4bca743b2c8149a70 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 15 Apr 2021 14:57:23 +0300 Subject: [PATCH 043/171] Add periods at the end of descriptions. Refactor position and naming --- internal/status/status.go | 75 +++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/internal/status/status.go b/internal/status/status.go index a9a45c6ab..eea7d625c 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -32,11 +32,38 @@ type FlagsStatus struct { var statusFlags = FlagsStatus{} +var Command = &command.Command{ + Cmd: &cobra.Command{ + Use: "status", + Short: "Display the status of the Flow network", + }, + Flags: &statusFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + // Get network name from global flag + network := globalFlags.Network + if network == "" { + network = command.NetworkEmulator + } + + accessNode, err := services.Status.Ping(network) + + return &Result{ + network: network, + accessNode: accessNode, + err: err, + }, nil + }, +} type Result struct { network string accessNode string - connectionError error + err error } @@ -48,62 +75,34 @@ const ( OfflineStatus = "OFFLINE" ) -// getStatus returns string representation for network status +// getStatus returns string representation for Flow network status. func (r *Result) getStatus() string { - if r.connectionError == nil { + if r.err == nil { return OnlineStatus } return OfflineStatus } -// getColoredStatus returns colored string representation for network status +// getColoredStatus returns colored string representation for Flow network status. func (r *Result) getColoredStatus() string { - if r.connectionError == nil { + if r.err == nil { return util.Green(OnlineStatus) } return util.Red(OfflineStatus) } -// getIcon returns emoji icon representing network statu +// getIcon returns emoji icon representing Flow network status. func (r *Result) getIcon() string { - if r.connectionError == nil { + if r.err == nil { return OnlineIcon } return OfflineIcon } -var InitCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "status", - Short: "Display status of network", - }, - Flags: &statusFlags, - Run: func( - cmd *cobra.Command, - args []string, - globalFlags command.GlobalFlags, - services *services.Services, - ) (command.Result, error) { - // Get network name from global flag - network := globalFlags.Network - if network == "" { - network = "emulator" - } - - accessNode, err := services.Status.Ping(network) - - return &Result{ - network: network, - accessNode: accessNode, - connectionError: err, - }, nil - }, -} - -// String convert result to string +// String converts result to a string. func (r *Result) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) @@ -116,7 +115,7 @@ func (r *Result) String() string { return b.String() } -// JSON convert result to JSON +// JSON converts result to a JSON. func (r *Result) JSON() interface{} { result := make(map[string]string) @@ -127,7 +126,7 @@ func (r *Result) JSON() interface{} { return result } -// Oneliner show result as one liner grep friendly +// Oneliner returns result as one liner grep friendly. func (r *Result) Oneliner() string { return r.getStatus() } From a0afd36df8c59655ddc811e647844f7e32fc8e9d Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 15 Apr 2021 14:58:01 +0300 Subject: [PATCH 044/171] Refactor Command naming --- cmd/flow/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index cbcf3981a..45af7a606 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -47,7 +47,7 @@ func main() { // hot commands config.InitCommand.AddToParent(cmd) - status.InitCommand.AddToParent(cmd) + status.Command.AddToParent(cmd) // structured commands cmd.AddCommand(cadence.Cmd) From 1a86a4ca6e9977141ffb6480a45bdf703a4ad7d6 Mon Sep 17 00:00:00 2001 From: Max Daunarovich Date: Thu, 15 Apr 2021 14:58:33 +0300 Subject: [PATCH 045/171] Update checksum file --- go.sum | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/go.sum b/go.sum index c15688bf5..14dc5561b 100644 --- a/go.sum +++ b/go.sum @@ -197,7 +197,6 @@ github.com/ethereum/go-ethereum v1.9.9/go.mod h1:a9TqabFudpDu1nucId+k9S8R9whYaHn github.com/ethereum/go-ethereum v1.9.13 h1:rOPqjSngvs1VSYH2H+PMPiWt4VEulvNRbFgqiGqJM3E= github.com/ethereum/go-ethereum v1.9.13/go.mod h1:qwN9d1GLyDh0N7Ab8bMGd0H9knaji2jOBm2RrMGjXls= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= @@ -206,7 +205,6 @@ github.com/flynn/noise v0.0.0-20180327030543-2492fe189ae6/go.mod h1:1i71OnUq3iUe github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -410,7 +408,6 @@ github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsj github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -437,16 +434,13 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -725,9 +719,7 @@ github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.2-0.20190409134802-7e037d187b0c/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onflow/cadence v0.13.0 h1:rMQpIwbZyqdiKV3f8nwxmyqyJahHcDRHDaZcjNH3sfI= github.com/onflow/cadence v0.13.0/go.mod h1:VuW4hf5AuC/PkxKD6akqq03Fgk0CpOM3ZOR6n7htNIw= -github.com/onflow/cadence v0.13.5-no-id-caching h1:mlC4seJ5MibmnXP3WTlClgqoTvdbEcRn++F851R8G30= github.com/onflow/cadence v0.13.5-no-id-caching/go.mod h1:EEXKRNuW5C2E1wRM4fLhfqoTgXohPFieXwOGJubz1Jg= github.com/onflow/cadence v0.13.6/go.mod h1:EEXKRNuW5C2E1wRM4fLhfqoTgXohPFieXwOGJubz1Jg= github.com/onflow/cadence v0.13.7 h1:y+ftev0THtmq6etDsiNMQMVlUiF5SeplUNKXSAH9vZ8= @@ -744,7 +736,6 @@ github.com/onflow/flow-ft/lib/go/contracts v0.4.0 h1:M1I4z027GHOLcjkj9lL2UUUpZpE github.com/onflow/flow-ft/lib/go/contracts v0.4.0/go.mod h1:1zoTjp1KzNnOPkyqKmWKerUyf0gciw+e6tAEt0Ks3JE= github.com/onflow/flow-go v0.14.9 h1:yfyvEWWXJ+66mtTf/pEDPO3hwBKaQh06WVuvAXN7Vao= github.com/onflow/flow-go v0.14.9/go.mod h1:EGaieLf+gZ/HGci8HEHxh6VeES9Sfpqo9ZggzzteejI= -github.com/onflow/flow-go-sdk v0.15.0 h1:h2FD/d1p/VRIWEcAYcVOT2rm4qKppIn4sVog+/eXKrw= github.com/onflow/flow-go-sdk v0.15.0/go.mod h1:Dkcd1xQta8EPQL5XKE9vi2OTa6CoMsbX0jIQ4ozhUUs= github.com/onflow/flow-go-sdk v0.16.2 h1:QVQoRgGoDZU1g7nJDzK+ticTMGLnjqFviwA6MBMTSOE= github.com/onflow/flow-go-sdk v0.16.2/go.mod h1:qbg42SwWPoVzr6BORyUoi7DFvRsyfeH0sxVDuhRZjfs= @@ -776,7 +767,6 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= @@ -854,7 +844,6 @@ github.com/segmentio/fasthash v1.0.2/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KR github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -874,11 +863,9 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= @@ -887,17 +874,14 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= @@ -928,7 +912,6 @@ github.com/thoas/go-funk v0.7.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xz github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/uber/jaeger-client-go v2.22.1+incompatible h1:NHcubEkVbahf9t3p75TOCR83gdUHXjRJvjoBh1yACsM= github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= @@ -1008,7 +991,6 @@ golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9 h1:phUcVbl53swtrUN8kQEXFhUxPlIlWyBfKmidCu7P95o= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -1087,7 +1069,6 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -1165,7 +1146,6 @@ golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201008064518-c1f3e3309c71 h1:ZPX6UakxrJCxWiyGWpXtFY+fp86Esy7xJT/jJCG8bgU= golang.org/x/sys v0.0.0-20201008064518-c1f3e3309c71/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1236,7 +1216,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca h1:pvScuB+UnCGDas2naNKUOXruM08MjwVcEdaweeynIqQ= golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -1249,7 +1228,6 @@ gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJ gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.6.1 h1:/LSrTrgZtpbXyAR6+0e152SROCkJJSh7goYWVmdPFGc= gonum.org/v1/gonum v0.6.1/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= @@ -1350,7 +1328,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 5a0598df26dcb10d7cfc40df8c33884a6e731465 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 16 Apr 2021 17:03:58 +0200 Subject: [PATCH 046/171] conflict resolution --- pkg/flowcli/contracts/contracts.go | 98 --------------------------- pkg/flowcli/contracts/preprocessor.go | 8 ++- pkg/flowcli/project/transaction.go | 21 +++--- 3 files changed, 18 insertions(+), 109 deletions(-) diff --git a/pkg/flowcli/contracts/contracts.go b/pkg/flowcli/contracts/contracts.go index 6bfae995f..79639b1c9 100644 --- a/pkg/flowcli/contracts/contracts.go +++ b/pkg/flowcli/contracts/contracts.go @@ -141,108 +141,10 @@ func (c *Contract) addAlias(location string, target flow.Address) { c.aliases[location] = target } -type Loader interface { - Load(source string) (string, error) - Normalize(base, relative string) string -} - -type FilesystemLoader struct{} - -func (f FilesystemLoader) Load(source string) (string, error) { - codeBytes, err := ioutil.ReadFile(source) - if err != nil { - return "", err - } - - return string(codeBytes), nil -} - -func (f FilesystemLoader) Normalize(base, relative string) string { - return absolutePath(base, relative) -} - func absolutePath(basePath, relativePath string) string { return path.Join(path.Dir(basePath), relativePath) } -type Preprocessor struct { - loader Loader - aliases map[string]string - contracts []*Contract - contractsBySource map[string]*Contract -} - -func NewPreprocessor(loader Loader, aliases map[string]string) *Preprocessor { - return &Preprocessor{ - loader: loader, - aliases: aliases, - contracts: make([]*Contract, 0), - contractsBySource: make(map[string]*Contract), - } -} - -func (p *Preprocessor) AddContractSource( - contractName, - contractSource string, - target flow.Address, - args []config.ContractArgument, -) error { - contractCode, err := p.loader.Load(contractSource) - if err != nil { - return err - } - - c, err := newContract( - len(p.contracts), - contractName, - contractSource, - contractCode, - target, - args, - ) - if err != nil { - return err - } - - p.contracts = append(p.contracts, c) - p.contractsBySource[c.source] = c - - return nil -} - -func (p *Preprocessor) ResolveImports() error { - for _, c := range p.contracts { - for _, location := range c.imports() { - importPath := p.loader.Normalize(c.source, location) - importAlias, isAlias := p.aliases[importPath] - importContract, isContract := p.contractsBySource[importPath] - - if isContract { - c.addDependency(location, importContract) - } else if isAlias { - c.addAlias(location, flow.HexToAddress(importAlias)) - } else { - return fmt.Errorf("Import from %s could not be found: %s, make sure import path is correct.", c.name, importPath) - } - } - } - - return nil -} - -func (p *Preprocessor) ContractBySource(contractSource string) *Contract { - return p.contractsBySource[contractSource] -} - -func (p *Preprocessor) ContractDeploymentOrder() ([]*Contract, error) { - sorted, err := sortByDeploymentOrder(p.contracts) - if err != nil { - return nil, err - } - - return sorted, nil -} - type CyclicImportError struct { Cycles [][]*Contract } diff --git a/pkg/flowcli/contracts/preprocessor.go b/pkg/flowcli/contracts/preprocessor.go index ba52186b0..baabae9c1 100644 --- a/pkg/flowcli/contracts/preprocessor.go +++ b/pkg/flowcli/contracts/preprocessor.go @@ -21,19 +21,19 @@ package contracts import ( "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-go-sdk" ) type Preprocessor struct { loader Loader - aliases project.Aliases + aliases map[string]string contracts []*Contract contractsBySource map[string]*Contract } -func NewPreprocessor(loader Loader, aliases project.Aliases) *Preprocessor { +func NewPreprocessor(loader Loader, aliases map[string]string) *Preprocessor { return &Preprocessor{ loader: loader, aliases: aliases, @@ -46,6 +46,7 @@ func (p *Preprocessor) AddContractSource( contractName, contractSource string, target flow.Address, + args []config.ContractArgument, ) error { contractCode, err := p.loader.Load(contractSource) if err != nil { @@ -58,6 +59,7 @@ func (p *Preprocessor) AddContractSource( contractSource, contractCode, target, + args, ) if err != nil { return err diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index ce9ed51e3..6b7bf9abf 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -94,15 +94,10 @@ func NewAddAccountContractTransaction( source string, args []config.ContractArgument, ) (*Transaction, error) { - contract := addAccountContractWithArgs(templates.Contract{ + return addAccountContractWithArgs(signer, templates.Contract{ Name: name, Source: source, }, args) - - return newTransactionFromTemplate( - templates.AddAccountContract(signer.Address(), contract), - signer, - ) } // NewRemoveAccountContractTransaction creates new transaction to remove contract @@ -114,9 +109,10 @@ func NewRemoveAccountContractTransaction(signer *Account, name string) (*Transac } func addAccountContractWithArgs( + signer *Account, contract templates.Contract, args []config.ContractArgument, -) *flow.Transaction { +) (*Transaction, error) { const addAccountContractTemplate = ` transaction(name: String, code: String%s) { prepare(signer: AuthAccount) { @@ -139,7 +135,16 @@ func addAccountContractWithArgs( } script := fmt.Sprintf(addAccountContractTemplate, txArgs, addArgs) - return tx.SetScript([]byte(script)) + tx.SetScript([]byte(script)) + + t := &Transaction{tx: tx} + err := t.SetSigner(signer) + if err != nil { + return nil, err + } + t.SetPayer(signer.Address()) + + return t, nil } // NewCreateAccountTransaction creates new transaction for account From 4dab467de2093fd1cab6339d7423b2d302f70be0 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 16 Apr 2021 17:30:01 +0200 Subject: [PATCH 047/171] fix --- pkg/flowcli/services/accounts.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index 580ae647d..9413bc98a 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -22,6 +22,8 @@ import ( "fmt" "strings" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli" "github.com/onflow/flow-cli/pkg/flowcli/gateway" "github.com/onflow/flow-cli/pkg/flowcli/output" From 1642c100dfa2197ef80cebbcd3a339b01be818e2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 16 Apr 2021 19:01:11 +0200 Subject: [PATCH 048/171] wip --- cmd/flow/main.go | 21 ++++++++ internal/accounts/accounts.go | 1 + internal/completion/completion.go | 82 +++++++++++++++++++++++++++++++ pkg/flowcli/services/accounts.go | 2 + 4 files changed, 106 insertions(+) create mode 100644 internal/completion/completion.go diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 93cbf7f6c..7fbfb61a1 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -20,6 +20,12 @@ package main import ( + "fmt" + "os" + "os/exec" + "strings" + + "github.com/onflow/flow-cli/internal/completion" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/accounts" @@ -42,8 +48,10 @@ func main() { var cmd = &cobra.Command{ Use: "flow", TraverseChildren: true, + ValidArgs: []string{"accounts"}, } + autocompletion(cmd) // hot commands config.InitCommand.AddToParent(cmd) @@ -60,9 +68,22 @@ func main() { cmd.AddCommand(collections.Cmd) cmd.AddCommand(project.Cmd) + cmd.AddCommand(completion.Cmd) + command.InitFlags(cmd) if err := cmd.Execute(); err != nil { util.Exit(1, err.Error()) } } + +func autocompletion(cmd *cobra.Command) { + shell := os.Getenv("SHELL") + + if strings.Contains(shell, "zsh") { + out, _ := exec.Command("echo ${fpath[1]}").Output() + fmt.Println("OUT:", out) + fmt.Println("OUT 2", os.Getenv("fpath")) + cmd.Root().GenZshCompletion(os.Stdout) + } +} diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index e3ebffff2..dce820710 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -32,6 +32,7 @@ var Cmd = &cobra.Command{ Use: "accounts", Short: "Utilities to manage accounts", TraverseChildren: true, + ValidArgs: []string{"get", "contract-add"}, } func init() { diff --git a/internal/completion/completion.go b/internal/completion/completion.go new file mode 100644 index 000000000..14aed1ff8 --- /dev/null +++ b/internal/completion/completion.go @@ -0,0 +1,82 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 completion + +import ( + "os" + + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "completion [bash|zsh|fish|powershell]", + Short: "Generate completion script", + Long: `To load completions: + +Bash: + + $ source <(yourprogram completion bash) + + # To load completions for each session, execute once: + # Linux: + $ yourprogram completion bash > /etc/bash_completion.d/yourprogram + # macOS: + $ yourprogram completion bash > /usr/local/etc/bash_completion.d/yourprogram + +Zsh: + + # If shell completion is not already enabled in your environment, + # you will need to enable it. You can execute the following once: + + $ echo "autoload -U compinit; compinit" >> ~/.zshrc + + # To load completions for each session, execute once: + $ yourprogram completion zsh > "${fpath[1]}/_yourprogram" + + # You will need to start a new shell for this setup to take effect. + +fish: + + $ yourprogram completion fish | source + + # To load completions for each session, execute once: + $ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish + +PowerShell: + + PS> yourprogram completion powershell | Out-String | Invoke-Expression + + # To load completions for every new session, run: + PS> yourprogram completion powershell > yourprogram.ps1 + # and source this file from your PowerShell profile. +`, + DisableFlagsInUseLine: true, + ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + Args: cobra.ExactValidArgs(1), + Run: func(cmd *cobra.Command, args []string) { + switch args[0] { + case "bash": + cmd.Root().GenBashCompletion(os.Stdout) + case "zsh": + cmd.Root().GenZshCompletion(os.Stdout) + case "powershell": + cmd.Root().GenPowerShellCompletion(os.Stdout) + } + }, +} diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index 580ae647d..9413bc98a 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -22,6 +22,8 @@ import ( "fmt" "strings" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli" "github.com/onflow/flow-cli/pkg/flowcli/gateway" "github.com/onflow/flow-cli/pkg/flowcli/output" From 89f190c1e1e1a97ac5d9b117f42ffabd52a083d1 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 19 Apr 2021 13:30:58 +0200 Subject: [PATCH 049/171] wip shell --- cmd/flow/main.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 7fbfb61a1..50d7a949a 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -48,7 +48,6 @@ func main() { var cmd = &cobra.Command{ Use: "flow", TraverseChildren: true, - ValidArgs: []string{"accounts"}, } autocompletion(cmd) @@ -81,9 +80,12 @@ func autocompletion(cmd *cobra.Command) { shell := os.Getenv("SHELL") if strings.Contains(shell, "zsh") { - out, _ := exec.Command("echo ${fpath[1]}").Output() - fmt.Println("OUT:", out) - fmt.Println("OUT 2", os.Getenv("fpath")) - cmd.Root().GenZshCompletion(os.Stdout) + c := exec.Command("zsh", "-c ", `echo -n ${fpath[1]}`) + path, err := c.Output() + if err != nil { + return + } + + cmd.GenZshCompletionFile(fmt.Sprintf("%s/_dflow", path)) } } From 5faf4f135b83e3e7b578653dc5db87abe81dd4b7 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:24:59 +0200 Subject: [PATCH 050/171] refactor to config setup completions --- cmd/flow/main.go | 21 +------------ internal/config/autocompletions.go | 49 ++++++++++++++++++++++++++++++ internal/config/config.go | 34 +++++++++++++++++++++ pkg/flowcli/output/prompt.go | 29 ++++++++++++++++++ 4 files changed, 113 insertions(+), 20 deletions(-) create mode 100644 internal/config/autocompletions.go create mode 100644 internal/config/config.go diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 50d7a949a..385740c9b 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -20,11 +20,6 @@ package main import ( - "fmt" - "os" - "os/exec" - "strings" - "github.com/onflow/flow-cli/internal/completion" "github.com/spf13/cobra" @@ -50,7 +45,6 @@ func main() { TraverseChildren: true, } - autocompletion(cmd) // hot commands config.InitCommand.AddToParent(cmd) @@ -66,6 +60,7 @@ func main() { cmd.AddCommand(blocks.Cmd) cmd.AddCommand(collections.Cmd) cmd.AddCommand(project.Cmd) + cmd.AddCommand(config.Cmd) cmd.AddCommand(completion.Cmd) @@ -75,17 +70,3 @@ func main() { util.Exit(1, err.Error()) } } - -func autocompletion(cmd *cobra.Command) { - shell := os.Getenv("SHELL") - - if strings.Contains(shell, "zsh") { - c := exec.Command("zsh", "-c ", `echo -n ${fpath[1]}`) - path, err := c.Output() - if err != nil { - return - } - - cmd.GenZshCompletionFile(fmt.Sprintf("%s/_dflow", path)) - } -} diff --git a/internal/config/autocompletions.go b/internal/config/autocompletions.go new file mode 100644 index 000000000..f3687f47b --- /dev/null +++ b/internal/config/autocompletions.go @@ -0,0 +1,49 @@ +package config + +import ( + "fmt" + "os" + "os/exec" + + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/spf13/cobra" +) + +var CompletionCmd = &cobra.Command{ + Use: "setup-completions [powershell]", + Short: "Setup command autocompletion", + DisableFlagsInUseLine: true, + ValidArgs: []string{"powershell"}, + Args: cobra.MaximumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + shell := "" + if len(args) == 1 { + shell = args[0] + } + + if shell == "powershell" { + cmd.Root().GenPowerShellCompletion(os.Stdout) + } else { + shell, shellOS := output.AutocompletionPrompt() + + if shell == "bash" && shellOS == "MacOS" { + cmd.Root().GenBashCompletionFile("/usr/local/etc/bash_completion.d/flow") + + fmt.Printf("Flow command completions installed in: /usr/local/etc/bash_completion.d/flow\n") + fmt.Printf("You will need to start a new shell for this setup to take effect.\n\n") + } else if shell == "bash" && shellOS == "Linux" { + cmd.Root().GenBashCompletionFile("/etc/bash_completion.d/flow") + + fmt.Printf("Flow command completions installed in: /etc/bash_completion.d/flow\n") + fmt.Printf("You will need to start a new shell for this setup to take effect.\n\n") + } else if shell == "zsh" { + c := exec.Command("zsh", "-c ", `echo -n ${fpath[1]}`) + path, _ := c.Output() + cmd.Root().GenZshCompletionFile(fmt.Sprintf("%s/_flow", path)) + + fmt.Printf("Flow command completions installed in: '%s/_flow'\n", path) + fmt.Printf("You will need to start a new shell for this setup to take effect.\n\n") + } + } + }, +} diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 000000000..c80249942 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,34 @@ +package config + +import ( + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "config", + Short: "Manage configuration", + TraverseChildren: true, +} + +func init() { + Cmd.AddCommand(CompletionCmd) +} + +// ConfigResult +type ConfigResult struct { +} + +// JSON convert result to JSON +func (c *ConfigResult) JSON() interface{} { + return nil +} + +// String convert result to string +func (c *ConfigResult) String() string { + return "" +} + +// Oneliner show result as one liner grep friendly +func (c *ConfigResult) Oneliner() string { + return "" +} diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index efe94623e..841d4c523 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -91,3 +91,32 @@ func ApproveTransactionPrompt(transaction *project.Transaction) bool { return result == "Yes" } + +func AutocompletionPrompt() (string, string) { + prompt := promptui.Select{ + Label: "❓ Select your shell (you can run 'echo $SHELL' to find out)", + Items: []string{"bash", "zsh", "powershell"}, + } + + _, shell, _ := prompt.Run() + os := "" + + switch shell { + case "bash": + prompt := promptui.Select{ + Label: "❓ Select operation system", + Items: []string{"MacOS", "Linux"}, + } + _, os, _ = prompt.Run() + case "powershell": + fmt.Printf(`PowerShell Instalation Guide: +PS> flow config setup-completions powershell | Out-String | Invoke-Expression + +# To load completions for every new session, run: +PS> flow config setup-completions powershell > flow.ps1 +# and source this file from your PowerShell profile. +`) + } + + return shell, os +} From 1a827554d98c6510790fc51981792281134f24ba Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:38:05 +0200 Subject: [PATCH 051/171] remove chain id from conf struct --- pkg/flowcli/config/config.go | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 303cbd50e..1c8da1ede 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -43,9 +43,8 @@ type Emulators []Emulator // Network defines the configuration for a Flow network. type Network struct { - Name string - Host string - ChainID flow.ChainID + Name string + Host string } // Deploy defines the configuration for a contract deployment. @@ -79,7 +78,6 @@ type Contract struct { type Account struct { Name string Address flow.Address - ChainID flow.ChainID Keys []AccountKey } @@ -114,27 +112,24 @@ const ( // DefaultEmulatorNetwork get default emulator network func DefaultEmulatorNetwork() Network { return Network{ - Name: "emulator", - Host: "127.0.0.1:3569", - ChainID: flow.Emulator, + Name: "emulator", + Host: "127.0.0.1:3569", } } // DefaultTestnetNetwork get default testnet network func DefaultTestnetNetwork() Network { return Network{ - Name: "testnet", - Host: "access.devnet.nodes.onflow.org:9000", - ChainID: flow.Testnet, + Name: "testnet", + Host: "access.devnet.nodes.onflow.org:9000", } } // DefaultMainnetNetwork get default mainnet network func DefaultMainnetNetwork() Network { return Network{ - Name: "mainnet", - Host: "access.mainnet.nodes.onflow.org:9000", - ChainID: flow.Mainnet, + Name: "mainnet", + Host: "access.mainnet.nodes.onflow.org:9000", } } From a15fd54ce9df0d409f56a7051c0af41e7593c369 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:44:12 +0200 Subject: [PATCH 052/171] remove advanced network --- pkg/flowcli/config/json/network.go | 60 +++++------------------------- 1 file changed, 9 insertions(+), 51 deletions(-) diff --git a/pkg/flowcli/config/json/network.go b/pkg/flowcli/config/json/network.go index a16920c78..52b4477b8 100644 --- a/pkg/flowcli/config/json/network.go +++ b/pkg/flowcli/config/json/network.go @@ -21,8 +21,6 @@ package json import ( "encoding/json" - "github.com/onflow/flow-go-sdk" - "github.com/onflow/flow-cli/pkg/flowcli/config" ) @@ -33,19 +31,9 @@ func (j jsonNetworks) transformToConfig() config.Networks { networks := make(config.Networks, 0) for networkName, n := range j { - var network config.Network - - if n.Host != "" { - network = config.Network{ - Name: networkName, - Host: n.Host, - } - } else { - network = config.Network{ - Name: networkName, - Host: n.Advanced.Host, - ChainID: flow.ChainID(n.Advanced.ChainID), - } + network := config.Network{ + Name: networkName, + Host: n.Host, } networks = append(networks, network) @@ -59,59 +47,29 @@ func transformNetworksToJSON(networks config.Networks) jsonNetworks { jsonNetworks := jsonNetworks{} for _, n := range networks { - // if simple case - if n.ChainID == "" { - jsonNetworks[n.Name] = jsonNetwork{ - Host: n.Host, - } - } else { // if advanced case - jsonNetworks[n.Name] = jsonNetwork{ - Advanced: advancedNetwork{ - Host: n.Host, - ChainID: n.ChainID.String(), - }, - } + jsonNetworks[n.Name] = jsonNetwork{ + Host: n.Host, } } return jsonNetworks } -type advancedNetwork struct { - Host string `json:"host"` - ChainID string `json:"chain"` -} - type jsonNetwork struct { - Host string - Advanced advancedNetwork + Host string } func (j *jsonNetwork) UnmarshalJSON(b []byte) error { - // simple var host string err := json.Unmarshal(b, &host) - if err == nil { - j.Host = host - return nil - } - - // advanced - var advanced advancedNetwork - err = json.Unmarshal(b, &advanced) - if err == nil { - j.Advanced = advanced - } else { + if err != nil { return err } + j.Host = host return nil } func (j jsonNetwork) MarshalJSON() ([]byte, error) { - if j.Host != "" { - return json.Marshal(j.Host) - } else { - return json.Marshal(j.Advanced) - } + return json.Marshal(j.Host) } From 4f9c239f0e3bbbf95378b32b8cb44b2a9c13302f Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:45:50 +0200 Subject: [PATCH 053/171] remove chain id account --- pkg/flowcli/config/json/account.go | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/pkg/flowcli/config/json/account.go b/pkg/flowcli/config/json/account.go index 8383c13ca..1353dea95 100644 --- a/pkg/flowcli/config/json/account.go +++ b/pkg/flowcli/config/json/account.go @@ -46,11 +46,10 @@ func transformChainID(rawChainID string, rawAddress string) flow.ChainID { } // transformAddress returns address based on address and chain id -func transformAddress(address string, rawChainID string) flow.Address { - chainID := transformChainID(rawChainID, address) - +func transformAddress(address string) flow.Address { + // only allow service for emulator if address == "service" { - return flow.ServiceAddress(chainID) + return flow.ServiceAddress(flow.Emulator) } return flow.HexToAddress(address) @@ -66,8 +65,7 @@ func (j jsonAccounts) transformToConfig() config.Accounts { if a.Simple.Address != "" { account = config.Account{ Name: accountName, - ChainID: transformChainID(a.Simple.Chain, a.Simple.Address), - Address: transformAddress(a.Simple.Address, a.Simple.Chain), + Address: transformAddress(a.Simple.Address), Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -93,8 +91,7 @@ func (j jsonAccounts) transformToConfig() config.Accounts { account = config.Account{ Name: accountName, - ChainID: transformChainID(a.Advanced.Chain, a.Advanced.Address), - Address: transformAddress(a.Advanced.Address, a.Advanced.Chain), + Address: transformAddress(a.Advanced.Address), Keys: keys, } } @@ -116,7 +113,6 @@ func transformSimpleAccountToJSON(a config.Account) jsonAccount { return jsonAccount{ Simple: jsonAccountSimple{ Address: a.Address.String(), - Chain: a.ChainID.String(), Keys: a.Keys[0].Context[config.PrivateKeyField], }, } @@ -138,7 +134,6 @@ func transformAdvancedAccountToJSON(a config.Account) jsonAccount { return jsonAccount{ Advanced: jsonAccountAdvanced{ Address: a.Address.String(), - Chain: a.ChainID.String(), Keys: keys, }, } @@ -163,12 +158,10 @@ func transformAccountsToJSON(accounts config.Accounts) jsonAccounts { type jsonAccountSimple struct { Address string `json:"address"` Keys string `json:"keys"` - Chain string `json:"chain"` } type jsonAccountAdvanced struct { Address string `json:"address"` - Chain string `json:"chain"` Keys []jsonAccountKey `json:"keys"` } From 13bd69bebe31225943147f6e12d3414d5db8f1e5 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:46:40 +0200 Subject: [PATCH 054/171] remove chain id tests --- pkg/flowcli/config/json/account_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pkg/flowcli/config/json/account_test.go b/pkg/flowcli/config/json/account_test.go index fa78c6557..cbf886a1b 100644 --- a/pkg/flowcli/config/json/account_test.go +++ b/pkg/flowcli/config/json/account_test.go @@ -40,7 +40,6 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { accounts := jsonAccounts.transformToConfig() assert.Equal(t, accounts.GetByName("test").Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, accounts.GetByName("test").ChainID.String(), "flow-emulator") assert.Len(t, accounts.GetByName("test").Keys, 1) assert.Equal(t, accounts.GetByName("test").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("test").Keys[0].Index, 0) @@ -75,7 +74,6 @@ func Test_ConfigAccountKeysAdvanced(t *testing.T) { account := accounts.GetByName("test") assert.Equal(t, account.Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, account.ChainID.String(), "flow-emulator") assert.Len(t, account.Keys, 1) assert.Equal(t, account.Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, account.Keys[0].Index, 0) @@ -119,7 +117,6 @@ func Test_ConfigAccountKeysAdvancedMultiple(t *testing.T) { account := accounts.GetByName("test") assert.Equal(t, account.Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, account.ChainID.String(), "flow-emulator") assert.Len(t, account.Keys, 2) assert.Equal(t, account.Keys[0].HashAlgo.String(), "SHA3_256") @@ -155,7 +152,6 @@ func Test_ConfigMultipleAccountsSimple(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Name, "emulator-account") assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "0000000000000000") - assert.Equal(t, accounts.GetByName("emulator-account").ChainID.String(), "flow-emulator") assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) @@ -163,7 +159,6 @@ func Test_ConfigMultipleAccountsSimple(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "2c1162386b0a245f") - assert.Equal(t, accounts.GetByName("testnet-account").ChainID.String(), "testnet") assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) @@ -212,7 +207,6 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { accounts := jsonAccounts.transformToConfig() assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, accounts.GetByName("emulator-account").ChainID.String(), "flow-emulator") assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) @@ -220,7 +214,6 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "1c1162386b0a245f") - assert.Equal(t, accounts.GetByName("testnet-account").ChainID.String(), "testnet") assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) @@ -259,7 +252,6 @@ func Test_ConfigMixedAccounts(t *testing.T) { accounts := jsonAccounts.transformToConfig() assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, accounts.GetByName("emulator-account").ChainID.String(), "flow-emulator") assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) @@ -267,7 +259,6 @@ func Test_ConfigMixedAccounts(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "3c1162386b0a245f") - assert.Equal(t, accounts.GetByName("testnet-account").ChainID.String(), "testnet") assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) From 2548b0a587819049f88dded8c1d4624874a621d5 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:48:23 +0200 Subject: [PATCH 055/171] remove chain id tests --- pkg/flowcli/config/config_test.go | 8 ++------ pkg/flowcli/project/project_test.go | 32 +++++++++-------------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/pkg/flowcli/config/config_test.go b/pkg/flowcli/config/config_test.go index ddfcf68c7..0b906e0dc 100644 --- a/pkg/flowcli/config/config_test.go +++ b/pkg/flowcli/config/config_test.go @@ -86,7 +86,6 @@ func generateComplexConfig() config.Config { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -99,7 +98,6 @@ func generateComplexConfig() config.Config { }, { Name: "account-2", Address: flow.HexToAddress("2c1162386b0a245f"), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -112,7 +110,6 @@ func generateComplexConfig() config.Config { }, { Name: "account-4", Address: flow.HexToAddress("f8d6e0586b0a20c1"), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -124,9 +121,8 @@ func generateComplexConfig() config.Config { }}, }}, Networks: config.Networks{{ - Name: "emulator", - Host: "127.0.0.1.3569", - ChainID: flow.Emulator, + Name: "emulator", + Host: "127.0.0.1.3569", }}, } } diff --git a/pkg/flowcli/project/project_test.go b/pkg/flowcli/project/project_test.go index 98575ad8f..899305f45 100644 --- a/pkg/flowcli/project/project_test.go +++ b/pkg/flowcli/project/project_test.go @@ -96,7 +96,6 @@ func generateComplexProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -109,7 +108,6 @@ func generateComplexProject() Project { }, { Name: "account-2", Address: flow.HexToAddress("2c1162386b0a245f"), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -122,7 +120,6 @@ func generateComplexProject() Project { }, { Name: "account-4", Address: flow.HexToAddress("f8d6e0586b0a20c1"), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -134,9 +131,8 @@ func generateComplexProject() Project { }}, }}, Networks: config.Networks{{ - Name: "emulator", - Host: "127.0.0.1.3569", - ChainID: flow.Emulator, + Name: "emulator", + Host: "127.0.0.1.3569", }}, } @@ -170,7 +166,6 @@ func generateSimpleProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -182,9 +177,8 @@ func generateSimpleProject() Project { }}, }}, Networks: config.Networks{{ - Name: "emulator", - Host: "127.0.0.1.3569", - ChainID: flow.Emulator, + Name: "emulator", + Host: "127.0.0.1.3569", }}, } @@ -223,7 +217,6 @@ func generateAliasesProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -235,9 +228,8 @@ func generateAliasesProject() Project { }}, }}, Networks: config.Networks{{ - Name: "emulator", - Host: "127.0.0.1.3569", - ChainID: flow.Emulator, + Name: "emulator", + Host: "127.0.0.1.3569", }}, } @@ -292,7 +284,6 @@ func generateAliasesComplexProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - ChainID: flow.Emulator, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -305,7 +296,6 @@ func generateAliasesComplexProject() Project { }, { Name: "testnet-account", Address: flow.HexToAddress("1e82856bf20e2aa6"), - ChainID: flow.Testnet, Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, @@ -317,13 +307,11 @@ func generateAliasesComplexProject() Project { }}, }}, Networks: config.Networks{{ - Name: "emulator", - Host: "127.0.0.1.3569", - ChainID: flow.Emulator, + Name: "emulator", + Host: "127.0.0.1.3569", }, { - Name: "testnet", - Host: "127.0.0.1.3569", - ChainID: flow.Testnet, + Name: "testnet", + Host: "127.0.0.1.3569", }}, } From b3647a616bc5d2c2c8611da35c79666da13ad086 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:48:30 +0200 Subject: [PATCH 056/171] account remove chain id --- pkg/flowcli/project/account.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/flowcli/project/account.go b/pkg/flowcli/project/account.go index bb1ecd5c7..a940bd833 100644 --- a/pkg/flowcli/project/account.go +++ b/pkg/flowcli/project/account.go @@ -97,7 +97,6 @@ func AccountFromConfig(accountConf config.Account) (*Account, error) { return &Account{ name: accountConf.Name, address: accountConf.Address, - chainID: accountConf.ChainID, keys: accountKeys, }, nil } @@ -122,7 +121,6 @@ func accountToConfig(account *Account) config.Account { return config.Account{ Name: account.name, Address: account.address, - ChainID: account.chainID, Keys: keyConfigs, } } From 95c1f5f6639fa8d70c25ce74fb2f975372980b58 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 15:58:38 +0200 Subject: [PATCH 057/171] tests fixed --- pkg/flowcli/config/json/account_test.go | 15 ++------------- pkg/flowcli/config/json/config_test.go | 8 ++------ pkg/flowcli/config/json/network_test.go | 8 ++------ pkg/flowcli/config/loader_test.go | 11 +++-------- 4 files changed, 9 insertions(+), 33 deletions(-) diff --git a/pkg/flowcli/config/json/account_test.go b/pkg/flowcli/config/json/account_test.go index cbf886a1b..3bbba9805 100644 --- a/pkg/flowcli/config/json/account_test.go +++ b/pkg/flowcli/config/json/account_test.go @@ -28,7 +28,6 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { b := []byte(`{ "test": { "address": "service", - "chain": "flow-emulator", "keys": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -51,7 +50,6 @@ func Test_ConfigAccountKeysAdvanced(t *testing.T) { b := []byte(`{ "test": { "address": "service", - "chain": "flow-emulator", "keys": [ { "type": "hex", @@ -85,7 +83,6 @@ func Test_ConfigAccountKeysAdvancedMultiple(t *testing.T) { b := []byte(`{ "test": { "address": "service", - "chain": "flow-emulator", "keys": [ { "type": "hex", @@ -134,12 +131,10 @@ func Test_ConfigMultipleAccountsSimple(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service-1", - "chain": "flow-emulator", "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" }, "testnet-account": { "address": "0x2c1162386b0a245f", - "chain": "testnet", "keys": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -170,7 +165,6 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service", - "chain": "flow-emulator", "keys": [ { "type": "hex", @@ -185,7 +179,6 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { }, "testnet-account": { "address": "1c1162386b0a245f", - "chain": "testnet", "keys": [ { "type": "0x18d6e0586b0a20c7", @@ -225,7 +218,6 @@ func Test_ConfigMixedAccounts(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service", - "chain": "flow-emulator", "keys": [ { "type": "hex", @@ -240,7 +232,6 @@ func Test_ConfigMixedAccounts(t *testing.T) { }, "testnet-account": { "address": "3c1162386b0a245f", - "chain": "testnet", "keys": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -270,12 +261,10 @@ func Test_ConfigAccountsMap(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service-1", - "chain": "flow-emulator", "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" }, "testnet-account": { "address": "3c1162386b0a245f", - "chain": "testnet", "keys": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -291,7 +280,7 @@ func Test_ConfigAccountsMap(t *testing.T) { } func Test_TransformDefaultAccountToJSON(t *testing.T) { - b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","chain":"flow-emulator","keys":[{"type":"hex","index":0,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47","chain":"testnet"}}`) + b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","keys":[{"type":"hex","index":0,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}`) var jsonAccounts jsonAccounts err := json.Unmarshal(b, &jsonAccounts) @@ -307,7 +296,7 @@ func Test_TransformDefaultAccountToJSON(t *testing.T) { } func Test_TransformAccountToJSON(t *testing.T) { - b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","chain":"flow-emulator","keys":[{"type":"hex","index":1,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47","chain":"testnet"}}`) + b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","keys":[{"type":"hex","index":1,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}`) var jsonAccounts jsonAccounts err := json.Unmarshal(b, &jsonAccounts) diff --git a/pkg/flowcli/config/json/config_test.go b/pkg/flowcli/config/json/config_test.go index bab46c201..04f88f914 100644 --- a/pkg/flowcli/config/json/config_test.go +++ b/pkg/flowcli/config/json/config_test.go @@ -33,16 +33,12 @@ func Test_SimpleJSONConfig(t *testing.T) { }, "contracts": {}, "networks": { - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator" - } + "emulator": "127.0.0.1:3569" }, "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - "chain": "flow-emulator" + "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } }, "deploys": {} diff --git a/pkg/flowcli/config/json/network_test.go b/pkg/flowcli/config/json/network_test.go index fd96f6b3a..1b95b3f27 100644 --- a/pkg/flowcli/config/json/network_test.go +++ b/pkg/flowcli/config/json/network_test.go @@ -41,11 +41,7 @@ func Test_ConfigNetworkSimple(t *testing.T) { func Test_ConfigNetworkMultiple(t *testing.T) { b := []byte(`{ - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator", - "serviceAccount": "emulator-service" - }, + "emulator": "127.0.0.1:3569", "testnet": "access.testnet.nodes.onflow.org:9000" }`) @@ -63,7 +59,7 @@ func Test_ConfigNetworkMultiple(t *testing.T) { } func Test_TransformNetworkToJSON(t *testing.T) { - b := []byte(`{"emulator":{"host":"127.0.0.1:3569","chain":"flow-emulator"},"testnet":"access.testnet.nodes.onflow.org:9000"}`) + b := []byte(`{"emulator":"127.0.0.1:3569","testnet":"access.testnet.nodes.onflow.org:9000"}`) var jsonNetworks jsonNetworks err := json.Unmarshal(b, &jsonNetworks) diff --git a/pkg/flowcli/config/loader_test.go b/pkg/flowcli/config/loader_test.go index 1645039ac..024ed3606 100644 --- a/pkg/flowcli/config/loader_test.go +++ b/pkg/flowcli/config/loader_test.go @@ -38,16 +38,12 @@ func Test_JSONSimple(t *testing.T) { }, "contracts": {}, "networks": { - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator" - } + "emulator": "127.0.0.1:3569" }, "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - "chain": "flow-emulator" + "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } }, "deployments": {} @@ -257,8 +253,7 @@ func Test_JSONEnv(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "$EMULATOR_KEY", - "chain": "flow-emulator" + "keys": "$EMULATOR_KEY" } } }`) From 86c973de1bf7af30a67d45aa784283d7aad57ce6 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 16:01:42 +0200 Subject: [PATCH 058/171] migration ignore old chain id format --- pkg/flowcli/config/json/network.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pkg/flowcli/config/json/network.go b/pkg/flowcli/config/json/network.go index 52b4477b8..49e2c09e2 100644 --- a/pkg/flowcli/config/json/network.go +++ b/pkg/flowcli/config/json/network.go @@ -59,15 +59,27 @@ type jsonNetwork struct { Host string } +type advancedNetwork struct { + Host string + Chain string +} + func (j *jsonNetwork) UnmarshalJSON(b []byte) error { var host string err := json.Unmarshal(b, &host) - if err != nil { - return err + if err == nil { + j.Host = host + return nil + } + + // ignore advanced schema from previous configuration format + var advanced advancedNetwork + err = json.Unmarshal(b, &advanced) + if err == nil { + j.Host = advanced.Host } - j.Host = host - return nil + return err } func (j jsonNetwork) MarshalJSON() ([]byte, error) { From 3f6ec111e08774fa35a2aa0e5ce5ce22776b0560 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 16:04:42 +0200 Subject: [PATCH 059/171] test ignore old chain id format --- pkg/flowcli/config/json/network_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/flowcli/config/json/network_test.go b/pkg/flowcli/config/json/network_test.go index 1b95b3f27..ba490aed4 100644 --- a/pkg/flowcli/config/json/network_test.go +++ b/pkg/flowcli/config/json/network_test.go @@ -72,3 +72,23 @@ func Test_TransformNetworkToJSON(t *testing.T) { assert.Equal(t, string(b), string(x)) } + +func Test_IngoreOldFormat(t *testing.T) { + b := []byte(`{ + "emulator":"127.0.0.1:3569", + "testnet":"access.testnet.nodes.onflow.org:9000", + "mainnet": { + "host": "access.mainnet.nodes.onflow.org:9000", + "chain": "flow-mainnet" + } + }`) + + var jsonNetworks jsonNetworks + err := json.Unmarshal(b, &jsonNetworks) + assert.NoError(t, err) + + conf := jsonNetworks.transformToConfig() + assert.Len(t, jsonNetworks, 3) + assert.Equal(t, conf.GetByName("testnet").Host, "access.testnet.nodes.onflow.org:9000") + assert.Equal(t, conf.GetByName("mainnet").Host, "access.mainnet.nodes.onflow.org:9000") +} From fc92d5a57c34c0becfcf14b8dbc31bdfb9d7cc09 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 16:09:05 +0200 Subject: [PATCH 060/171] resolve conflicts --- pkg/flowcli/project/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 969ecc6ba..925e7d779 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -189,7 +189,7 @@ func (p *Project) ContractsByNetwork(network string) ([]Contract, error) { for _, deploymentContract := range deploy.Contracts { c := p.conf.Contracts.GetByNameAndNetwork(deploymentContract.Name, network) if c == nil { - return nil, fmt.Errorf("could not find contract with name name %s in the configuration", contractName) + return nil, fmt.Errorf("could not find contract with name name %s in the configuration", deploymentContract.Name) } contract := Contract{ From 768448a7c622115e39ee676ea1bbba8128ab6048 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 16:22:30 +0200 Subject: [PATCH 061/171] update docs --- docs/configuration.md | 50 ++++++++----------------------------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index 3352b4b53..2b143de2c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -25,24 +25,14 @@ Flow configuration (`flow.json`) file will contain the following properties: } }, "networks": { - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator" - }, - "mainnet": { - "host": "access.mainnet.nodes.onflow.org:9000", - "chain": "flow-mainnet" - }, - "testnet": { - "host": "access.devnet.nodes.onflow.org:9000", - "chain": "flow-testnet" - } + "emulator": "127.0.0.1:3569", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" }, "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", "keys": "ae1b44c0f5e8f6992ef2348898a35e50a8b0b9684000da8b1dade1b3bcd6ebee", - "chain": "flow-emulator" } }, "deployments": {}, @@ -98,23 +88,13 @@ We'll walk through each property one by one. "emulator-account": { "address": "f8d6e0586b0a20c7", "keys": "2eae2f31cb5b756151fa11d82949c634b8f28796a711d7eb1e52cc301ed11111", - "chain": "flow-emulator" } }, "networks": { - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator" - }, - "mainnet": { - "host": "access.mainnet.nodes.onflow.org:9000", - "chain": "flow-mainnet" - }, - "testnet": { - "host": "access.devnet.nodes.onflow.org:9000", - "chain": "flow-testnet" - } + "emulator": "127.0.0.1:3569", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" }, "emulators": { @@ -208,7 +188,6 @@ value that is defined on the run time to the default service address on the emul "accounts": { "admin-account-multiple-keys": { "address": "service", - "chain": "flow-emulator", "keys": [ { "type": "hex", @@ -270,24 +249,13 @@ contracts and networks, all of which are referenced by name. Use this section to define networks and connection parameters for that specific network. -#### Simple format - ```json ... "networks": { - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator" - }, - "mainnet": { - "host": "access.mainnet.nodes.onflow.org:9000", - "chain": "flow-mainnet" - }, - "testnet": { - "host": "access.devnet.nodes.onflow.org:9000", - "chain": "flow-testnet" - } + "emulator": "127.0.0.1:3569", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" } ... From 1978696b1bafaac5a83386d94f8ae5a130037932 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 16:22:40 +0200 Subject: [PATCH 062/171] remove chain id --- pkg/flowcli/config/json/account.go | 16 ---------------- pkg/flowcli/config/processor_test.go | 18 ++++++------------ pkg/flowcli/project/account.go | 4 ---- 3 files changed, 6 insertions(+), 32 deletions(-) diff --git a/pkg/flowcli/config/json/account.go b/pkg/flowcli/config/json/account.go index 1353dea95..02b66205c 100644 --- a/pkg/flowcli/config/json/account.go +++ b/pkg/flowcli/config/json/account.go @@ -25,26 +25,10 @@ import ( "github.com/onflow/flow-go-sdk/crypto" "github.com/onflow/flow-cli/pkg/flowcli/config" - "github.com/onflow/flow-cli/pkg/flowcli/util" ) type jsonAccounts map[string]jsonAccount -// transformChainID return chain id based on address and chain id -func transformChainID(rawChainID string, rawAddress string) flow.ChainID { - if rawAddress == "service" && rawChainID == "" { - return flow.Emulator - } - - if rawChainID == "" { - address := flow.HexToAddress(rawAddress) - chainID, _ := util.GetAddressNetwork(address) - return chainID - } - - return flow.ChainID(rawChainID) -} - // transformAddress returns address based on address and chain id func transformAddress(address string) flow.Address { // only allow service for emulator diff --git a/pkg/flowcli/config/processor_test.go b/pkg/flowcli/config/processor_test.go index bb97661f9..d05c808fe 100644 --- a/pkg/flowcli/config/processor_test.go +++ b/pkg/flowcli/config/processor_test.go @@ -32,8 +32,7 @@ func Test_PrivateKeyEnv(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "$TEST", - "chain": "flow-emulator" + "keys": "$TEST" } } }`) @@ -44,8 +43,7 @@ func Test_PrivateKeyEnv(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "123", - "chain": "flow-emulator" + "keys": "123" } } }`, string(result)) @@ -59,8 +57,7 @@ func Test_PrivateKeyEnvMultipleAccounts(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "$TEST", - "chain": "flow-emulator" + "keys": "$TEST" } } }`) @@ -71,8 +68,7 @@ func Test_PrivateKeyEnvMultipleAccounts(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "123", - "chain": "flow-emulator" + "keys": "123" } } }`, string(result)) @@ -83,8 +79,7 @@ func Test_PrivateConfigFileAccounts(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - "chain": "flow-emulator" + "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account": { "fromFile": "test.json" } } @@ -98,8 +93,7 @@ func Test_PrivateConfigFileAccounts(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - "chain": "flow-emulator" + "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`, string(preprocessor)) diff --git a/pkg/flowcli/project/account.go b/pkg/flowcli/project/account.go index a940bd833..2c76e1270 100644 --- a/pkg/flowcli/project/account.go +++ b/pkg/flowcli/project/account.go @@ -31,7 +31,6 @@ import ( type Account struct { name string address flow.Address - chainID flow.ChainID keys []AccountKey } @@ -72,12 +71,10 @@ func accountsFromConfig(conf *config.Config) ([]*Account, error) { func AccountFromAddressAndKey(address flow.Address, privateKey crypto.PrivateKey) *Account { key := NewHexAccountKeyFromPrivateKey(0, crypto.SHA3_256, privateKey) - chainID, _ := util.GetAddressNetwork(address) return &Account{ name: "", address: address, - chainID: chainID, keys: []AccountKey{key}, } } @@ -141,7 +138,6 @@ func generateEmulatorServiceAccount(sigAlgo crypto.SignatureAlgorithm, hashAlgo return &Account{ name: config.DefaultEmulatorServiceAccountName, address: flow.ServiceAddress(flow.Emulator), - chainID: flow.Emulator, keys: []AccountKey{ serviceAccountKey, }, From 480261a270bd6b2849153611982716fb97b9d4a9 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 17:01:40 +0200 Subject: [PATCH 063/171] update resolve network to resolve to coded defaults --- internal/command/command.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index fb2cd2d40..0f54067c8 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -207,6 +207,12 @@ func createGateway(host string) (gateway.Gateway, error) { } // resolveHost from the flags provided +// +// Resolve the network host in the following order: +// 1. if host flag is provided resolve to that host +// 2. if conf is initialized return host by network flag +// 3. if conf is not initialized and network flag is provided resolve to coded value for that network +// 4. default to emulator network func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (string, error) { // don't allow both network and host flag as the host might be different if networkFlag != config.DefaultEmulatorNetwork().Name && hostFlag != "" { @@ -226,8 +232,13 @@ func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (st return proj.NetworkByName(networkFlag).Host, nil } - // default to emulator host - return config.DefaultEmulatorNetwork().Host, nil + + networks := config.DefaultNetworks() + if networks.GetByName(networkFlag) != nil { + return networks.GetByName(networkFlag).Host, nil + } else { + return "", fmt.Errorf("invalid network with name %s", networkFlag) + } } // create logger utility From 8778a3a599bb72728db9d50b4f52658a958a37d1 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 18:25:25 +0200 Subject: [PATCH 064/171] Version 0.18.0 --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index 6b60281ad..a86d3df72 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v0.17.0 +v0.18.0 From eccfa5805b2bf045129c28b1a6d1da27f49c473d Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 20 Apr 2021 20:25:57 +0200 Subject: [PATCH 065/171] added test step in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 90ee8f061..24f9241d0 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ You can find the CLI documentation on the [Flow documentation website](https://d - Tag a new release and push it - Build the binaries: `make versioned-binaries` +- Test built binaries locally - Upload the binaries: `make publish` - Update the Homebrew formula: e.g. `brew bump-formula-pr flow-cli --version=0.12.3` From 7ac1c34798910080ff207b0b790b12d5e500d837 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 08:35:25 +0200 Subject: [PATCH 066/171] move default config var location --- internal/config/init.go | 4 +++- internal/emulator/start.go | 2 +- internal/project/init.go | 1 + pkg/flowcli/config/config.go | 5 +++++ pkg/flowcli/project/project.go | 5 ----- pkg/flowcli/services/project.go | 14 +++++++++++--- 6 files changed, 21 insertions(+), 10 deletions(-) diff --git a/internal/config/init.go b/internal/config/init.go index 5571ecdf6..955bb1219 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -35,7 +35,8 @@ 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 flow.json config file"` + Reset bool `default:"false" flag:"reset" info:"Reset configuration file"` + Global bool `default:"false" flag:"global" info:"Initialize global user configuration"` } var initFlag = FlagsInit{} @@ -54,6 +55,7 @@ var InitCommand = &command.Command{ ) (command.Result, error) { proj, err := services.Project.Init( initFlag.Reset, + initFlag.Global, initFlag.ServiceKeySigAlgo, initFlag.ServiceKeyHashAlgo, initFlag.ServicePrivateKey, diff --git a/internal/emulator/start.go b/internal/emulator/start.go index c2795b7db..88b392089 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -61,7 +61,7 @@ func ConfiguredServiceKey( if err != nil { util.Exitf(1, err.Error()) } else { - err = proj.Save(project.DefaultConfigPath) + err = proj.Save(config.DefaultConfigPath) if err != nil { util.Exitf(1, err.Error()) } diff --git a/internal/project/init.go b/internal/project/init.go index 33d6d710a..a25d1b1aa 100644 --- a/internal/project/init.go +++ b/internal/project/init.go @@ -47,6 +47,7 @@ var InitCommand = &command.Command{ proj, err := services.Project.Init( initFlag.Reset, + initFlag.Global, initFlag.ServiceKeySigAlgo, initFlag.ServiceKeyHashAlgo, initFlag.ServicePrivateKey, diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 7a5870b83..0347befae 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -111,6 +111,11 @@ const ( DefaultEmulatorServiceAccountName = "emulator-account" ) +var ( + DefaultConfigPaths = []string{"flow.json"} + DefaultConfigPath = DefaultConfigPaths[0] +) + // DefaultEmulatorNetwork get default emulator network func DefaultEmulatorNetwork() Network { return Network{ diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 925e7d779..9bcd66e65 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -34,11 +34,6 @@ import ( "github.com/onflow/flow-cli/pkg/flowcli/config/json" ) -var ( - DefaultConfigPaths = []string{"flow.json"} - DefaultConfigPath = DefaultConfigPaths[0] -) - // Project contains the configuration for a Flow project. type Project struct { composer *config.Loader diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index f3a6683ab..efb770714 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -22,6 +22,8 @@ import ( "fmt" "strings" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-go-sdk/crypto" "github.com/onflow/flow-cli/pkg/flowcli/contracts" @@ -53,14 +55,20 @@ func NewProject( func (p *Project) Init( reset bool, + global bool, serviceKeySigAlgo string, serviceKeyHashAlgo string, servicePrivateKey string, ) (*project.Project, error) { - if project.Exists(project.DefaultConfigPath) && !reset { + path := config.DefaultConfigPath + if global { + path = "" + } + + if project.Exists(path) && !reset { return nil, fmt.Errorf( "configuration already exists at: %s, if you want to reset configuration use the reset flag", - project.DefaultConfigPath, + config.DefaultConfigPath, ) } @@ -83,7 +91,7 @@ func (p *Project) Init( proj.SetEmulatorServiceKey(serviceKey) } - err = proj.Save(project.DefaultConfigPath) + err = proj.Save(path) if err != nil { return nil, err } From 311969ce06a9578455c426f7e9e0fb1550da9552 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 08:35:38 +0200 Subject: [PATCH 067/171] new global flag --- internal/command/command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/command/command.go b/internal/command/command.go index fb2cd2d40..d254dd1fa 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -86,7 +86,7 @@ var Flags = GlobalFlags{ Network: config.DefaultEmulatorNetwork().Name, Log: logLevelInfo, Yes: false, - ConfigPath: project.DefaultConfigPaths, + ConfigPath: config.DefaultConfigPaths, } // InitFlags init all the global persistent flags From 8dc6e72f2586179be0be5a3ad1d6a7b03ff00983 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 14:28:45 +0200 Subject: [PATCH 068/171] move configs paths to config --- pkg/flowcli/config/config.go | 27 ++++++++++++++++++++++----- pkg/flowcli/services/project.go | 6 +++--- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 0347befae..72ef78321 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -20,6 +20,8 @@ package config import ( "errors" + "fmt" + "os" "github.com/onflow/cadence" @@ -111,11 +113,6 @@ const ( DefaultEmulatorServiceAccountName = "emulator-account" ) -var ( - DefaultConfigPaths = []string{"flow.json"} - DefaultConfigPath = DefaultConfigPaths[0] -) - // DefaultEmulatorNetwork get default emulator network func DefaultEmulatorNetwork() Network { return Network{ @@ -176,6 +173,26 @@ func DefaultEmulators() Emulators { var ErrOutdatedFormat = errors.New("you are using old configuration format") +const DefaultPath = "flow.json" + +// GlobalPath gets global path based on home dir +func GlobalPath() string { + dirname, err := os.UserHomeDir() + if err != nil { + return "" + } + + return fmt.Sprintf("%s/.%s", dirname, DefaultPath) +} + +// DefaultPaths determines default paths for configuration +func DefaultPaths() []string { + return []string{ + GlobalPath(), + DefaultPath, + } +} + // IsAlias checks if contract has an alias func (c *Contract) IsAlias() bool { return c.Alias != "" diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index efb770714..c6c23f158 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -60,15 +60,15 @@ func (p *Project) Init( serviceKeyHashAlgo string, servicePrivateKey string, ) (*project.Project, error) { - path := config.DefaultConfigPath + path := config.DefaultPath if global { - path = "" + path = config.GlobalPath() } if project.Exists(path) && !reset { return nil, fmt.Errorf( "configuration already exists at: %s, if you want to reset configuration use the reset flag", - config.DefaultConfigPath, + path, ) } From 171d76cafbe942e8f0eab7f5d3b3ee759b718616 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 14:29:13 +0200 Subject: [PATCH 069/171] refactor new config path func, check for network exists --- internal/command/command.go | 41 ++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index d254dd1fa..f154a581c 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -55,14 +55,14 @@ type Command struct { } type GlobalFlags struct { - Filter string - Format string - Save string - Host string - Log string - Network string - Yes bool - ConfigPath []string + Filter string + Format string + Save string + Host string + Log string + Network string + Yes bool + ConfigPaths []string } const ( @@ -79,14 +79,14 @@ const ( ) var Flags = GlobalFlags{ - Filter: "", - Format: formatText, - Save: "", - Host: "", - Network: config.DefaultEmulatorNetwork().Name, - Log: logLevelInfo, - Yes: false, - ConfigPath: config.DefaultConfigPaths, + Filter: "", + Format: formatText, + Save: "", + Host: "", + Network: config.DefaultEmulatorNetwork().Name, + Log: logLevelInfo, + Yes: false, + ConfigPaths: config.DefaultPaths(), } // InitFlags init all the global persistent flags @@ -132,10 +132,10 @@ func InitFlags(cmd *cobra.Command) { ) cmd.PersistentFlags().StringSliceVarP( - &Flags.ConfigPath, + &Flags.ConfigPaths, "config-path", "f", - Flags.ConfigPath, + Flags.ConfigPaths, "Path to flow configuration file", ) @@ -163,7 +163,8 @@ func InitFlags(cmd *cobra.Command) { func (c Command) AddToParent(parent *cobra.Command) { c.Cmd.Run = func(cmd *cobra.Command, args []string) { // initialize project but ignore error since config can be missing - proj, err := project.Load(Flags.ConfigPath) + proj, err := project.Load(Flags.ConfigPaths) + // here we ignore if config does not exist as some commands don't require it if !errors.Is(err, config.ErrDoesNotExist) && cmd.CommandPath() != "flow init" { // ignore configs errors if we are doing init config handleError("Config Error", err) @@ -225,6 +226,8 @@ func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (st } return proj.NetworkByName(networkFlag).Host, nil + } else if networkFlag != config.DefaultEmulatorNetwork().Name { + return "", fmt.Errorf("network not found, make sure flow configuration exists") } // default to emulator host return config.DefaultEmulatorNetwork().Host, nil From 07e381fafbaf8dde5b3a5a7cf5074d242151ead9 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 14:29:30 +0200 Subject: [PATCH 070/171] loader load global config --- pkg/flowcli/config/loader.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/pkg/flowcli/config/loader.go b/pkg/flowcli/config/loader.go index 8ced3d89b..07f30847b 100644 --- a/pkg/flowcli/config/loader.go +++ b/pkg/flowcli/config/loader.go @@ -107,16 +107,21 @@ func (l *Loader) Save(conf *Config, path string) error { func (l *Loader) Load(paths []string) (*Config, error) { var baseConf *Config - for _, path := range paths { - raw, err := l.loadFile(path) + for _, confPath := range paths { + raw, err := l.loadFile(confPath) + // if we don't find local config or global config skip as either may miss + if err != nil && (confPath == DefaultPath || confPath == GlobalPath()) { + continue + } + if err != nil { return nil, err } preProcessed := l.preprocess(raw) - configParser := l.configParsers.FindForFormat(filepath.Ext(path)) + configParser := l.configParsers.FindForFormat(filepath.Ext(confPath)) if configParser == nil { - return nil, fmt.Errorf("Parser not found for config: %s", path) + return nil, fmt.Errorf("parser not found for config: %s", confPath) } conf, err := configParser.Deserialize(preProcessed) @@ -133,6 +138,11 @@ func (l *Loader) Load(paths []string) (*Config, error) { l.composeConfig(baseConf, conf) } + // if no config was loaded - neither local nor global return an error + if baseConf == nil { + return nil, fmt.Errorf("configuration not found, create one using `flow init`") + } + baseConf, err := l.postprocess(baseConf) if err != nil { return nil, err From 4425c1457d7732e687e33161371451605d8baae2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 14:29:53 +0200 Subject: [PATCH 071/171] save new config to conf vars --- internal/emulator/start.go | 4 ++-- pkg/flowcli/project/project.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/emulator/start.go b/internal/emulator/start.go index 88b392089..f2ccc5c88 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -61,13 +61,13 @@ func ConfiguredServiceKey( if err != nil { util.Exitf(1, err.Error()) } else { - err = proj.Save(config.DefaultConfigPath) + err = proj.Save(config.DefaultPath) if err != nil { util.Exitf(1, err.Error()) } } } else { - proj, err = project.Load(command.Flags.ConfigPath) + proj, err = project.Load(command.Flags.ConfigPaths) if err != nil { if errors.Is(err, config.ErrDoesNotExist) { util.Exitf(1, "🙏 Configuration is missing, initialize it with: 'flow init' and then rerun this command.") diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 9bcd66e65..f8e124b7d 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -50,12 +50,12 @@ type Contract struct { } // Load loads a project configuration and returns the resulting project. -func Load(configFilePath []string) (*Project, error) { +func Load(configFilePaths []string) (*Project, error) { composer := config.NewLoader(afero.NewOsFs()) // here we add all available parsers (more to add yaml etc...) composer.AddConfigParser(json.NewParser()) - conf, err := composer.Load(configFilePath) + conf, err := composer.Load(configFilePaths) if err != nil { if errors.Is(err, config.ErrDoesNotExist) { From d533d735e5cb2ec600db13f80dc5daf52786b438 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 14:41:10 +0200 Subject: [PATCH 072/171] added docs for global conf --- docs/initialize-configuration.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/initialize-configuration.md b/docs/initialize-configuration.md index bca85847e..c480ddd64 100644 --- a/docs/initialize-configuration.md +++ b/docs/initialize-configuration.md @@ -34,18 +34,42 @@ or by removing the configuration file first. ❌ Command Error: configuration already exists at: flow.json, if you want to reset configuration use the reset flag ``` +## Global Configuration + +Flow supports global configuration which is a `.flow.json` file saved in your home +directory and loaded as the first configuration file wherever you execute the CLI command. + +Please be aware that global configuration has the lowest priority and is overwritten +by any other configuration file if they exist (if `flow.json` exist in your current +directory it will overwrite properties in global configuration, but only those which overlap). + +You can generate a global configuration using `--global` flag. + +Command example: `flow init --global`. + +Global flow configuration is saved as: +- MacOs: `~/.flow.json` +- Linux: `~/.flow.json` +- Windows: `C:\Users\$USER\.flow.json` + ## Flags ### Reset -- Flag: `reset` +- Flag: `--reset` Using this flag will reset the existing configuration and create a new one. +### Global + +- Flag: `--global` + +Using this flag will create a global Flow configuration. + ### Service Private Key -- Flag: `service-private-key` +- Flag: `--service-private-key` - Valid inputs: a hex-encoded private key in raw form. Private key used on the default service account. @@ -53,7 +77,7 @@ Private key used on the default service account. ### Service Key Signature Algorithm -- Flag: `--sig-algo` +- Flag: `--service-sig-algo` - Valid inputs: `"ECDSA_P256", "ECDSA_secp256k1"` - Default: `"ECDSA_P256"` @@ -63,7 +87,7 @@ Flow supports the secp256k1 and P-256 curves. ### Service Key Hash Algorithm -- Flag: `--hash-algo` +- Flag: `--service-hash-algo` - Valid inputs: `"SHA2_256", "SHA3_256"` - Default: `"SHA3_256"` From 5afd514f5250a8507341f9d34e8b3c32de6233c4 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:00:14 +0200 Subject: [PATCH 073/171] add dotenv support --- go.mod | 1 + go.sum | 2 ++ pkg/flowcli/config/processor.go | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/go.mod b/go.mod index b1ce19c7f..adb09819a 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/a8m/envsubst v1.2.0 github.com/fatih/color v1.7.0 github.com/gosuri/uilive v0.0.4 + github.com/joho/godotenv v1.3.0 // indirect github.com/magiconair/properties v1.8.1 // indirect github.com/manifoldco/promptui v0.8.0 github.com/onflow/cadence v0.14.4 diff --git a/go.sum b/go.sum index 7ec8efcb2..4d39713f1 100644 --- a/go.sum +++ b/go.sum @@ -400,6 +400,8 @@ github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZl github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/bitset v1.0.0 h1:Ws0PXV3PwXqWK2n7Vz6idCdrV/9OrBXgHEJi27ZB9Dw= diff --git a/pkg/flowcli/config/processor.go b/pkg/flowcli/config/processor.go index 164c00a70..5bb3a617b 100644 --- a/pkg/flowcli/config/processor.go +++ b/pkg/flowcli/config/processor.go @@ -22,6 +22,8 @@ import ( "regexp" "strings" + "github.com/joho/godotenv" + "github.com/a8m/envsubst" ) @@ -41,6 +43,8 @@ func ProcessorRun(raw []byte) ([]byte, map[string]string) { // processEnv finds env variables and insert env values func processEnv(raw string) string { + godotenv.Load() // try to load .env file + raw, _ = envsubst.String(raw) return raw } From 307b0cfe1579aab735435263edabc900e1fe6c79 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:05:53 +0200 Subject: [PATCH 074/171] docs support --- docs/security.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/security.md b/docs/security.md index b1c52a72d..c718aac73 100644 --- a/docs/security.md +++ b/docs/security.md @@ -38,7 +38,8 @@ that is not checked into source control (e.g. excluded with `.gitignore`). #### Private configuration file -**Put this file in `.gitignore`:** +⚠️ Put this file in `.gitignore`: + ```json // flow.testnet.json { @@ -75,6 +76,19 @@ PRIVATE_KEY=key flow project deploy } ``` +### Private Environment File + +Setting environment variables can be avoided by using environment file `.env`. Anything +you put in `.env` file will be loaded as environment variable and replaced in configuration the +same way as environment variable. + +⚠️ Please be sure to add `.env` file to `.gitignore` + +Example `.env` file: +```bash +PRIVATE_KEY=123 +``` + ### Composing Multiple Configuration Files You can merge multiple configuration files like so: From 282a2d139ce5b63dc8ba341c0195aa12c6e39f9c Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:51:04 +0200 Subject: [PATCH 075/171] remove keys from json --- pkg/flowcli/config/json/account.go | 68 ++++++++++++------------------ 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/pkg/flowcli/config/json/account.go b/pkg/flowcli/config/json/account.go index 8383c13ca..a1e0e7e33 100644 --- a/pkg/flowcli/config/json/account.go +++ b/pkg/flowcli/config/json/account.go @@ -68,34 +68,28 @@ func (j jsonAccounts) transformToConfig() config.Accounts { Name: accountName, ChainID: transformChainID(a.Simple.Chain, a.Simple.Address), Address: transformAddress(a.Simple.Address, a.Simple.Chain), - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, HashAlgo: crypto.SHA3_256, Context: map[string]string{ - config.PrivateKeyField: a.Simple.Keys, + config.PrivateKeyField: a.Simple.Key, }, - }}, + }, } } else { // advanced format - keys := make([]config.AccountKey, 0) - for _, key := range a.Advanced.Keys { - key := config.AccountKey{ - Type: key.Type, - Index: key.Index, - SigAlgo: crypto.StringToSignatureAlgorithm(key.SigAlgo), - HashAlgo: crypto.StringToHashAlgorithm(key.HashAlgo), - Context: key.Context, - } - keys = append(keys, key) - } - account = config.Account{ Name: accountName, ChainID: transformChainID(a.Advanced.Chain, a.Advanced.Address), Address: transformAddress(a.Advanced.Address, a.Advanced.Chain), - Keys: keys, + Key: config.AccountKey{ + Type: a.Advanced.Key.Type, + Index: a.Advanced.Key.Index, + SigAlgo: crypto.StringToSignatureAlgorithm(a.Advanced.Key.SigAlgo), + HashAlgo: crypto.StringToHashAlgorithm(a.Advanced.Key.HashAlgo), + Context: a.Advanced.Key.Context, + }, } } @@ -105,11 +99,11 @@ func (j jsonAccounts) transformToConfig() config.Accounts { return accounts } -func isDefaultKeyFormat(keys []config.AccountKey) bool { - return len(keys) == 1 && keys[0].Index == 0 && - keys[0].Type == config.KeyTypeHex && - keys[0].SigAlgo == crypto.ECDSA_P256 && - keys[0].HashAlgo == crypto.SHA3_256 +func isDefaultKeyFormat(key config.AccountKey) bool { + return key.Index == 0 && + key.Type == config.KeyTypeHex && + key.SigAlgo == crypto.ECDSA_P256 && + key.HashAlgo == crypto.SHA3_256 } func transformSimpleAccountToJSON(a config.Account) jsonAccount { @@ -117,29 +111,23 @@ func transformSimpleAccountToJSON(a config.Account) jsonAccount { Simple: jsonAccountSimple{ Address: a.Address.String(), Chain: a.ChainID.String(), - Keys: a.Keys[0].Context[config.PrivateKeyField], + Key: a.Key.Context[config.PrivateKeyField], }, } } func transformAdvancedAccountToJSON(a config.Account) jsonAccount { - var keys []jsonAccountKey - - for _, k := range a.Keys { - keys = append(keys, jsonAccountKey{ - Type: k.Type, - Index: k.Index, - SigAlgo: k.SigAlgo.String(), - HashAlgo: k.HashAlgo.String(), - Context: k.Context, - }) - } - return jsonAccount{ Advanced: jsonAccountAdvanced{ Address: a.Address.String(), Chain: a.ChainID.String(), - Keys: keys, + Key: jsonAccountKey{ + Type: a.Key.Type, + Index: a.Key.Index, + SigAlgo: a.Key.SigAlgo.String(), + HashAlgo: a.Key.HashAlgo.String(), + Context: a.Key.Context, + }, }, } } @@ -150,7 +138,7 @@ func transformAccountsToJSON(accounts config.Accounts) jsonAccounts { for _, a := range accounts { // if simple - if isDefaultKeyFormat(a.Keys) { + if isDefaultKeyFormat(a.Key) { jsonAccounts[a.Name] = transformSimpleAccountToJSON(a) } else { // if advanced jsonAccounts[a.Name] = transformAdvancedAccountToJSON(a) @@ -162,14 +150,14 @@ func transformAccountsToJSON(accounts config.Accounts) jsonAccounts { type jsonAccountSimple struct { Address string `json:"address"` - Keys string `json:"keys"` + Key string `json:"key"` Chain string `json:"chain"` } type jsonAccountAdvanced struct { - Address string `json:"address"` - Chain string `json:"chain"` - Keys []jsonAccountKey `json:"keys"` + Address string `json:"address"` + Chain string `json:"chain"` + Key jsonAccountKey `json:"key"` } type jsonAccountKey struct { From c0cc379517f866a9b09c819f9ff2d9581dbd7846 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:51:13 +0200 Subject: [PATCH 076/171] remove keys from account --- pkg/flowcli/project/account.go | 53 ++++++++++------------------------ 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/pkg/flowcli/project/account.go b/pkg/flowcli/project/account.go index bb1ecd5c7..c277c7675 100644 --- a/pkg/flowcli/project/account.go +++ b/pkg/flowcli/project/account.go @@ -32,7 +32,7 @@ type Account struct { name string address flow.Address chainID flow.ChainID - keys []AccountKey + key AccountKey } func (a *Account) Address() flow.Address { @@ -43,16 +43,12 @@ func (a *Account) Name() string { return a.name } -func (a *Account) Keys() []AccountKey { - return a.keys +func (a *Account) Key() AccountKey { + return a.key } -func (a *Account) DefaultKey() AccountKey { - return a.keys[0] -} - -func (a *Account) SetDefaultKey(key AccountKey) { - a.keys[0] = key +func (a *Account) SetKey(key AccountKey) { + a.key = key } func accountsFromConfig(conf *config.Config) ([]*Account, error) { @@ -71,34 +67,27 @@ func accountsFromConfig(conf *config.Config) ([]*Account, error) { } func AccountFromAddressAndKey(address flow.Address, privateKey crypto.PrivateKey) *Account { - key := NewHexAccountKeyFromPrivateKey(0, crypto.SHA3_256, privateKey) chainID, _ := util.GetAddressNetwork(address) return &Account{ name: "", address: address, chainID: chainID, - keys: []AccountKey{key}, + key: NewHexAccountKeyFromPrivateKey(0, crypto.SHA3_256, privateKey), } } -func AccountFromConfig(accountConf config.Account) (*Account, error) { - accountKeys := make([]AccountKey, 0, len(accountConf.Keys)) - - for _, key := range accountConf.Keys { - accountKey, err := NewAccountKey(key) - if err != nil { - return nil, err - } - - accountKeys = append(accountKeys, accountKey) +func AccountFromConfig(account config.Account) (*Account, error) { + key, err := NewAccountKey(account.Key) + if err != nil { + return nil, err } return &Account{ - name: accountConf.Name, - address: accountConf.Address, - chainID: accountConf.ChainID, - keys: accountKeys, + name: account.Name, + address: account.Address, + chainID: account.ChainID, + key: key, }, nil } @@ -113,17 +102,11 @@ func accountsToConfig(accounts []*Account) config.Accounts { } func accountToConfig(account *Account) config.Account { - keyConfigs := make([]config.AccountKey, 0, len(account.keys)) - - for _, key := range account.keys { - keyConfigs = append(keyConfigs, key.ToConfig()) - } - return config.Account{ Name: account.name, Address: account.address, ChainID: account.chainID, - Keys: keyConfigs, + Key: account.key.ToConfig(), } } @@ -138,14 +121,10 @@ func generateEmulatorServiceAccount(sigAlgo crypto.SignatureAlgorithm, hashAlgo return nil, fmt.Errorf("failed to generate emulator service key: %v", err) } - serviceAccountKey := NewHexAccountKeyFromPrivateKey(0, hashAlgo, privateKey) - return &Account{ name: config.DefaultEmulatorServiceAccountName, address: flow.ServiceAddress(flow.Emulator), chainID: flow.Emulator, - keys: []AccountKey{ - serviceAccountKey, - }, + key: NewHexAccountKeyFromPrivateKey(0, hashAlgo, privateKey), }, nil } From dd13180aee11dff3b55b91cbde71f5c706532565 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:51:23 +0200 Subject: [PATCH 077/171] remove keys from config account --- pkg/flowcli/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 7a5870b83..72ca130bb 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -80,7 +80,7 @@ type Account struct { Name string Address flow.Address ChainID flow.ChainID - Keys []AccountKey + Key AccountKey } // AccountKey defines the configuration for a Flow account key. From 14dc266cb368f32a0933b7027019aee58e3ad39a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:51:34 +0200 Subject: [PATCH 078/171] remove keys from tests --- pkg/flowcli/config/config_test.go | 12 +-- pkg/flowcli/config/json/account_test.go | 127 +++++++----------------- pkg/flowcli/config/json/config_test.go | 2 +- pkg/flowcli/config/loader_test.go | 10 +- pkg/flowcli/project/project_test.go | 36 +++---- 5 files changed, 67 insertions(+), 120 deletions(-) diff --git a/pkg/flowcli/config/config_test.go b/pkg/flowcli/config/config_test.go index ddfcf68c7..e365ae289 100644 --- a/pkg/flowcli/config/config_test.go +++ b/pkg/flowcli/config/config_test.go @@ -87,7 +87,7 @@ func generateComplexConfig() config.Config { Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -95,12 +95,12 @@ func generateComplexConfig() config.Config { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }, { Name: "account-2", Address: flow.HexToAddress("2c1162386b0a245f"), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -108,12 +108,12 @@ func generateComplexConfig() config.Config { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }, { Name: "account-4", Address: flow.HexToAddress("f8d6e0586b0a20c1"), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -121,7 +121,7 @@ func generateComplexConfig() config.Config { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }}, Networks: config.Networks{{ Name: "emulator", diff --git a/pkg/flowcli/config/json/account_test.go b/pkg/flowcli/config/json/account_test.go index fa78c6557..6aa02f121 100644 --- a/pkg/flowcli/config/json/account_test.go +++ b/pkg/flowcli/config/json/account_test.go @@ -41,11 +41,11 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { assert.Equal(t, accounts.GetByName("test").Address.String(), "f8d6e0586b0a20c7") assert.Equal(t, accounts.GetByName("test").ChainID.String(), "flow-emulator") - assert.Len(t, accounts.GetByName("test").Keys, 1) - assert.Equal(t, accounts.GetByName("test").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("test").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("test").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("test").Keys[0].Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("test").Key, 1) + assert.Equal(t, accounts.GetByName("test").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("test").Key.Index, 0) + assert.Equal(t, accounts.GetByName("test").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("test").Key.Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigAccountKeysAdvanced(t *testing.T) { @@ -76,61 +76,10 @@ func Test_ConfigAccountKeysAdvanced(t *testing.T) { assert.Equal(t, account.Address.String(), "f8d6e0586b0a20c7") assert.Equal(t, account.ChainID.String(), "flow-emulator") - assert.Len(t, account.Keys, 1) - assert.Equal(t, account.Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, account.Keys[0].Index, 0) - assert.Equal(t, account.Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, account.Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") -} - -func Test_ConfigAccountKeysAdvancedMultiple(t *testing.T) { - b := []byte(`{ - "test": { - "address": "service", - "chain": "flow-emulator", - "keys": [ - { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } - }, - { - "type": "hex", - "index": 1, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "2372967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } - } - ] - } - }`) - - var jsonAccounts jsonAccounts - err := json.Unmarshal(b, &jsonAccounts) - assert.NoError(t, err) - - accounts := jsonAccounts.transformToConfig() - account := accounts.GetByName("test") - - assert.Equal(t, account.Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, account.ChainID.String(), "flow-emulator") - assert.Len(t, account.Keys, 2) - - assert.Equal(t, account.Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, account.Keys[0].Index, 0) - assert.Equal(t, account.Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, account.Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") - - assert.Equal(t, account.Keys[1].HashAlgo.String(), "SHA3_256") - assert.Equal(t, account.Keys[1].Index, 1) - assert.Equal(t, account.Keys[1].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, account.Keys[1].Context["privateKey"], "2372967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, account.Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, account.Key.Index, 0) + assert.Equal(t, account.Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, account.Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigMultipleAccountsSimple(t *testing.T) { @@ -156,19 +105,17 @@ func Test_ConfigMultipleAccountsSimple(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Name, "emulator-account") assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "0000000000000000") assert.Equal(t, accounts.GetByName("emulator-account").ChainID.String(), "flow-emulator") - assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, accounts.GetByName("emulator-account").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("emulator-account").Key.Index, 0) + assert.Equal(t, accounts.GetByName("emulator-account").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("emulator-account").Key.Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "2c1162386b0a245f") assert.Equal(t, accounts.GetByName("testnet-account").ChainID.String(), "testnet") - assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Context["privateKey"], "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, accounts.GetByName("testnet-account").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("testnet-account").Key.Index, 0) + assert.Equal(t, accounts.GetByName("testnet-account").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("testnet-account").Key.Context["privateKey"], "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { @@ -213,19 +160,17 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "f8d6e0586b0a20c7") assert.Equal(t, accounts.GetByName("emulator-account").ChainID.String(), "flow-emulator") - assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, accounts.GetByName("emulator-account").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("emulator-account").Key.Index, 0) + assert.Equal(t, accounts.GetByName("emulator-account").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("emulator-account").Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "1c1162386b0a245f") assert.Equal(t, accounts.GetByName("testnet-account").ChainID.String(), "testnet") - assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, accounts.GetByName("testnet-account").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("testnet-account").Key.Index, 0) + assert.Equal(t, accounts.GetByName("testnet-account").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("testnet-account").Key.Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigMixedAccounts(t *testing.T) { @@ -260,19 +205,17 @@ func Test_ConfigMixedAccounts(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "f8d6e0586b0a20c7") assert.Equal(t, accounts.GetByName("emulator-account").ChainID.String(), "flow-emulator") - assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, accounts.GetByName("emulator-account").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("emulator-account").Key.Index, 0) + assert.Equal(t, accounts.GetByName("emulator-account").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("emulator-account").Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "3c1162386b0a245f") assert.Equal(t, accounts.GetByName("testnet-account").ChainID.String(), "testnet") - assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, accounts.GetByName("testnet-account").Key.HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("testnet-account").Key.Index, 0) + assert.Equal(t, accounts.GetByName("testnet-account").Key.SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("testnet-account").Key.Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigAccountsMap(t *testing.T) { @@ -329,3 +272,7 @@ func Test_TransformAccountToJSON(t *testing.T) { assert.Equal(t, string(b), string(x)) } + +func Test_SupportForOldFormatWithMultipleKeys(t *testing.T) { + assert.Fail(t, "todo") +} diff --git a/pkg/flowcli/config/json/config_test.go b/pkg/flowcli/config/json/config_test.go index bab46c201..928ebdf59 100644 --- a/pkg/flowcli/config/json/config_test.go +++ b/pkg/flowcli/config/json/config_test.go @@ -54,6 +54,6 @@ func Test_SimpleJSONConfig(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 1, len(conf.Accounts)) assert.Equal(t, "emulator-account", conf.Accounts[0].Name) - assert.Equal(t, "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Keys[0].Context["privateKey"]) + assert.Equal(t, "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Key.Context["privateKey"]) assert.Equal(t, "127.0.0.1:3569", conf.Networks.GetByName("emulator").Host) } diff --git a/pkg/flowcli/config/loader_test.go b/pkg/flowcli/config/loader_test.go index 1645039ac..faf39fa76 100644 --- a/pkg/flowcli/config/loader_test.go +++ b/pkg/flowcli/config/loader_test.go @@ -64,7 +64,7 @@ func Test_JSONSimple(t *testing.T) { assert.NoError(t, loadErr) assert.Equal(t, 1, len(conf.Accounts)) - assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Keys[0].Context["privateKey"]) + assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Key.Context["privateKey"]) } func Test_ComposeJSON(t *testing.T) { @@ -101,11 +101,11 @@ func Test_ComposeJSON(t *testing.T) { assert.NoError(t, loadErr) assert.Equal(t, 2, len(conf.Accounts)) assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - conf.Accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], + conf.Accounts.GetByName("emulator-account").Key.Context["privateKey"], ) assert.NotNil(t, conf.Accounts.GetByName("admin-account")) assert.Equal(t, "3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - conf.Accounts.GetByName("admin-account").Keys[0].Context["privateKey"], + conf.Accounts.GetByName("admin-account").Key.Context["privateKey"], ) } @@ -144,7 +144,7 @@ func Test_ComposeJSONOverwrite(t *testing.T) { assert.Equal(t, 1, len(conf.Accounts)) assert.NotNil(t, conf.Accounts.GetByName("admin-account")) assert.Equal(t, "3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - conf.Accounts.GetByName("admin-account").Keys[0].Context["privateKey"], + conf.Accounts.GetByName("admin-account").Key.Context["privateKey"], ) } @@ -276,5 +276,5 @@ func Test_JSONEnv(t *testing.T) { assert.NoError(t, loadErr) assert.Equal(t, 1, len(conf.Accounts)) - assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Keys[0].Context["privateKey"]) + assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Key.Context["privateKey"]) } diff --git a/pkg/flowcli/project/project_test.go b/pkg/flowcli/project/project_test.go index 4806ddb2b..7b1185a64 100644 --- a/pkg/flowcli/project/project_test.go +++ b/pkg/flowcli/project/project_test.go @@ -97,7 +97,7 @@ func generateComplexProject() Project { Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -105,12 +105,12 @@ func generateComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }, { Name: "account-2", Address: flow.HexToAddress("2c1162386b0a245f"), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -118,12 +118,12 @@ func generateComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }, { Name: "account-4", Address: flow.HexToAddress("f8d6e0586b0a20c1"), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -131,7 +131,7 @@ func generateComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }}, Networks: config.Networks{{ Name: "emulator", @@ -171,7 +171,7 @@ func generateSimpleProject() Project { Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -179,7 +179,7 @@ func generateSimpleProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }}, Networks: config.Networks{{ Name: "emulator", @@ -224,7 +224,7 @@ func generateAliasesProject() Project { Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -232,7 +232,7 @@ func generateAliasesProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }}, Networks: config.Networks{{ Name: "emulator", @@ -293,7 +293,7 @@ func generateAliasesComplexProject() Project { Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), ChainID: flow.Emulator, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -301,12 +301,12 @@ func generateAliasesComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }, { Name: "testnet-account", Address: flow.HexToAddress("1e82856bf20e2aa6"), ChainID: flow.Testnet, - Keys: []config.AccountKey{{ + Key: config.AccountKey{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -314,7 +314,7 @@ func generateAliasesComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }}, + }, }}, Networks: config.Networks{{ Name: "emulator", @@ -354,7 +354,7 @@ func Test_EmulatorConfigSimple(t *testing.T) { emulatorServiceAccount, _ := p.EmulatorServiceAccount() assert.Equal(t, emulatorServiceAccount.name, "emulator-account") - assert.Equal(t, emulatorServiceAccount.keys[0].ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, emulatorServiceAccount.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, flow.ServiceAddress("flow-emulator").String(), emulatorServiceAccount.Address().String()) } @@ -370,7 +370,7 @@ func Test_AccountByNameSimple(t *testing.T) { acc := p.AccountByName("emulator-account") assert.Equal(t, flow.ServiceAddress("flow-emulator").String(), acc.Address().String()) - assert.Equal(t, acc.DefaultKey().ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, acc.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_HostSimple(t *testing.T) { @@ -433,7 +433,7 @@ func Test_EmulatorConfigComplex(t *testing.T) { emulatorServiceAccount, _ := p.EmulatorServiceAccount() assert.Equal(t, emulatorServiceAccount.name, "emulator-account") - assert.Equal(t, emulatorServiceAccount.keys[0].ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, emulatorServiceAccount.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, emulatorServiceAccount.Address().String(), flow.ServiceAddress("flow-emulator").String()) } @@ -451,7 +451,7 @@ func Test_AccountByNameComplex(t *testing.T) { acc := p.AccountByName("account-2") assert.Equal(t, acc.Address().String(), "2c1162386b0a245f") - assert.Equal(t, acc.DefaultKey().ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, acc.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_HostComplex(t *testing.T) { From 3ece4d45d6fce7b3a2d3ddb60138a760f23a5465 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:51:51 +0200 Subject: [PATCH 079/171] fix single key in other files --- internal/emulator/start.go | 2 +- pkg/flowcli/project/project.go | 6 +++--- pkg/flowcli/project/transaction.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/emulator/start.go b/internal/emulator/start.go index c2795b7db..1d923f8f6 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -79,7 +79,7 @@ func ConfiguredServiceKey( serviceAccount, _ := proj.EmulatorServiceAccount() - serviceKeyHex, ok := serviceAccount.DefaultKey().(*project.HexAccountKey) + serviceKeyHex, ok := serviceAccount.Key().(*project.HexAccountKey) if !ok { util.Exit(1, "Only hexadecimal keys can be used as the emulator service account key.") } diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 925e7d779..b6ac99acb 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -165,10 +165,10 @@ func (p *Project) EmulatorServiceAccount() (*Account, error) { // SetEmulatorServiceKey sets the default emulator service account private key. func (p *Project) SetEmulatorServiceKey(privateKey crypto.PrivateKey) { acc := p.AccountByName(config.DefaultEmulatorServiceAccountName) - acc.SetDefaultKey( + acc.SetKey( NewHexAccountKeyFromPrivateKey( - acc.DefaultKey().Index(), - acc.DefaultKey().HashAlgo(), + acc.Key().Index(), + acc.Key().HashAlgo(), privateKey, ), ) diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index 6b7bf9abf..17b1c572e 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -219,7 +219,7 @@ func (t *Transaction) SetScriptWithArgs(script []byte, args []string, argsJSON s // SetSigner sets the signer for transaction func (t *Transaction) SetSigner(account *Account) error { - err := account.DefaultKey().Validate() + err := account.Key().Validate() if err != nil { return err } @@ -298,8 +298,8 @@ func (t *Transaction) AddAuthorizers(authorizers []flow.Address) *Transaction { // Sign signs transaction using signer account func (t *Transaction) Sign() (*Transaction, error) { - keyIndex := t.signer.DefaultKey().Index() - signer, err := t.signer.DefaultKey().Signer(context.Background()) + keyIndex := t.signer.Key().Index() + signer, err := t.signer.Key().Signer(context.Background()) if err != nil { return nil, err } From d47aba5fcd2251e95e0be6a44aedb7bddaea7e35 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 15:55:58 +0200 Subject: [PATCH 080/171] correct tests --- pkg/flowcli/config/json/account_test.go | 89 +++++++++++-------------- pkg/flowcli/config/json/config_test.go | 2 +- pkg/flowcli/config/loader_test.go | 26 ++++---- 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/pkg/flowcli/config/json/account_test.go b/pkg/flowcli/config/json/account_test.go index 6aa02f121..a5355e150 100644 --- a/pkg/flowcli/config/json/account_test.go +++ b/pkg/flowcli/config/json/account_test.go @@ -29,7 +29,7 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { "test": { "address": "service", "chain": "flow-emulator", - "keys": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "key": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -41,7 +41,6 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { assert.Equal(t, accounts.GetByName("test").Address.String(), "f8d6e0586b0a20c7") assert.Equal(t, accounts.GetByName("test").ChainID.String(), "flow-emulator") - assert.Len(t, accounts.GetByName("test").Key, 1) assert.Equal(t, accounts.GetByName("test").Key.HashAlgo.String(), "SHA3_256") assert.Equal(t, accounts.GetByName("test").Key.Index, 0) assert.Equal(t, accounts.GetByName("test").Key.SigAlgo.String(), "ECDSA_P256") @@ -53,17 +52,15 @@ func Test_ConfigAccountKeysAdvanced(t *testing.T) { "test": { "address": "service", "chain": "flow-emulator", - "keys": [ - { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } - ] + } } }`) @@ -87,12 +84,12 @@ func Test_ConfigMultipleAccountsSimple(t *testing.T) { "emulator-account": { "address": "service-1", "chain": "flow-emulator", - "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "key": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" }, "testnet-account": { "address": "0x2c1162386b0a245f", "chain": "testnet", - "keys": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "key": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -123,32 +120,28 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { "emulator-account": { "address": "service", "chain": "flow-emulator", - "keys": [ - { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } - ] + } }, "testnet-account": { "address": "1c1162386b0a245f", "chain": "testnet", - "keys": [ - { - "type": "0x18d6e0586b0a20c7", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } + "key": { + "type": "0x18d6e0586b0a20c7", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } - ] + } } }`) @@ -178,22 +171,20 @@ func Test_ConfigMixedAccounts(t *testing.T) { "emulator-account": { "address": "service", "chain": "flow-emulator", - "keys": [ - { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } + "key": { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } - ] + } }, "testnet-account": { "address": "3c1162386b0a245f", "chain": "testnet", - "keys": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "key": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -223,12 +214,12 @@ func Test_ConfigAccountsMap(t *testing.T) { "emulator-account": { "address": "service-1", "chain": "flow-emulator", - "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "key": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" }, "testnet-account": { "address": "3c1162386b0a245f", "chain": "testnet", - "keys": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "key": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -243,7 +234,7 @@ func Test_ConfigAccountsMap(t *testing.T) { } func Test_TransformDefaultAccountToJSON(t *testing.T) { - b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","chain":"flow-emulator","keys":[{"type":"hex","index":0,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47","chain":"testnet"}}`) + b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","chain":"flow-emulator","key":{"type":"hex","index":0,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}},"testnet-account":{"address":"3c1162386b0a245f","key":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47","chain":"testnet"}}`) var jsonAccounts jsonAccounts err := json.Unmarshal(b, &jsonAccounts) @@ -259,7 +250,7 @@ func Test_TransformDefaultAccountToJSON(t *testing.T) { } func Test_TransformAccountToJSON(t *testing.T) { - b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","chain":"flow-emulator","keys":[{"type":"hex","index":1,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47","chain":"testnet"}}`) + b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","chain":"flow-emulator","key":{"type":"hex","index":1,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}},"testnet-account":{"address":"3c1162386b0a245f","key":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47","chain":"testnet"}}`) var jsonAccounts jsonAccounts err := json.Unmarshal(b, &jsonAccounts) diff --git a/pkg/flowcli/config/json/config_test.go b/pkg/flowcli/config/json/config_test.go index 928ebdf59..f361a6673 100644 --- a/pkg/flowcli/config/json/config_test.go +++ b/pkg/flowcli/config/json/config_test.go @@ -41,7 +41,7 @@ func Test_SimpleJSONConfig(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", + "key": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", "chain": "flow-emulator" } }, diff --git a/pkg/flowcli/config/loader_test.go b/pkg/flowcli/config/loader_test.go index faf39fa76..c5b60167f 100644 --- a/pkg/flowcli/config/loader_test.go +++ b/pkg/flowcli/config/loader_test.go @@ -46,7 +46,7 @@ func Test_JSONSimple(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", + "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", "chain": "flow-emulator" } }, @@ -72,7 +72,7 @@ func Test_ComposeJSON(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -81,7 +81,7 @@ func Test_ComposeJSON(t *testing.T) { "accounts":{ "admin-account":{ "address":"f1d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -114,7 +114,7 @@ func Test_ComposeJSONOverwrite(t *testing.T) { "accounts": { "admin-account": { "address": "f8d6e0586b0a20c7", - "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -123,7 +123,7 @@ func Test_ComposeJSONOverwrite(t *testing.T) { "accounts":{ "admin-account":{ "address":"f1d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -153,7 +153,7 @@ func Test_FromFileAccountSimple(t *testing.T) { "accounts": { "service-account": { "address": "f8d6e0586b0a20c7", - "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account": { "fromFile": "private.json" } } @@ -163,7 +163,7 @@ func Test_FromFileAccountSimple(t *testing.T) { "accounts":{ "admin-account":{ "address":"f1d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -192,7 +192,7 @@ func Test_FromFileAccountComplex(t *testing.T) { "accounts": { "service-account": { "address": "f8d6e0586b0a20c7", - "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account-1": { "fromFile": "private.json" }, "admin-account-3": { "fromFile": "private.json" }, @@ -204,15 +204,15 @@ func Test_FromFileAccountComplex(t *testing.T) { "accounts":{ "admin-account-1":{ "address":"f1d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account-2":{ "address":"f2d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account-3":{ "address":"f3d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -221,7 +221,7 @@ func Test_FromFileAccountComplex(t *testing.T) { "accounts":{ "admin-account-5":{ "address":"f5d6e0586b0a20c7", - "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -257,7 +257,7 @@ func Test_JSONEnv(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "$EMULATOR_KEY", + "key": "$EMULATOR_KEY", "chain": "flow-emulator" } } From eaeafc862d447d72c559763aac17bc0fd960a0f4 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 16:18:31 +0200 Subject: [PATCH 081/171] add old format support --- pkg/flowcli/config/json/account.go | 37 ++++++++++++++++++++++- pkg/flowcli/config/json/account_test.go | 40 ++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/config/json/account.go b/pkg/flowcli/config/json/account.go index a1e0e7e33..2394f33d8 100644 --- a/pkg/flowcli/config/json/account.go +++ b/pkg/flowcli/config/json/account.go @@ -20,6 +20,7 @@ package json import ( "encoding/json" + "fmt" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" @@ -168,6 +169,16 @@ type jsonAccountKey struct { Context map[string]string `json:"context"` } +type jsonAccountSimpleOld struct { + Address string `json:"address"` + Keys string `json:"keys"` +} + +type jsonAccountAdvancedOld struct { + Address string `json:"address"` + Keys []jsonAccountKey `json:"keys"` +} + type jsonAccount struct { Simple jsonAccountSimple Advanced jsonAccountAdvanced @@ -175,9 +186,33 @@ type jsonAccount struct { func (j *jsonAccount) UnmarshalJSON(b []byte) error { + fmt.Println("IN", string(b)) + + // try simple old format + var simpleOld jsonAccountSimpleOld + err := json.Unmarshal(b, &simpleOld) + if err == nil { + j.Simple = jsonAccountSimple{ + Address: simpleOld.Address, + Key: simpleOld.Keys, + } + return nil + } + + // try advanced old format + var advancedOld jsonAccountAdvancedOld + err = json.Unmarshal(b, &advancedOld) + if err == nil { + j.Advanced = jsonAccountAdvanced{ + Address: advancedOld.Address, + Key: advancedOld.Keys[0], + } + return nil + } + // try simple format var simple jsonAccountSimple - err := json.Unmarshal(b, &simple) + err = json.Unmarshal(b, &simple) if err == nil { j.Simple = simple return nil diff --git a/pkg/flowcli/config/json/account_test.go b/pkg/flowcli/config/json/account_test.go index a5355e150..0e1dde7ad 100644 --- a/pkg/flowcli/config/json/account_test.go +++ b/pkg/flowcli/config/json/account_test.go @@ -265,5 +265,43 @@ func Test_TransformAccountToJSON(t *testing.T) { } func Test_SupportForOldFormatWithMultipleKeys(t *testing.T) { - assert.Fail(t, "todo") + b := []byte(`{ + "emulator-account": { + "address": "service-1", + "chain": "flow-emulator", + "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + }, + "testnet-account": { + "address": "3c1162386b0a245f", + "chain": "testnet", + "keys": [ + { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } + },{ + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "2332967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b44" + } + } + ] + } + }`) + + var jsonAccounts jsonAccounts + err := json.Unmarshal(b, &jsonAccounts) + assert.NoError(t, err) + + conf := jsonAccounts.transformToConfig() + + assert.Equal(t, conf.GetByName("testnet-account").Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, conf.GetByName("emulator-account").Key.Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } From 005819570c564e629d6989b06a4ba9d3ac0661f7 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 16:35:58 +0200 Subject: [PATCH 082/171] refactor decide format more reliably --- pkg/flowcli/config/json/account.go | 84 +++++++++++++++++++----------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/pkg/flowcli/config/json/account.go b/pkg/flowcli/config/json/account.go index 2394f33d8..4189588a6 100644 --- a/pkg/flowcli/config/json/account.go +++ b/pkg/flowcli/config/json/account.go @@ -20,7 +20,6 @@ package json import ( "encoding/json" - "fmt" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" @@ -184,49 +183,74 @@ type jsonAccount struct { Advanced jsonAccountAdvanced } +type FormatType int + +const ( + simpleFormat FormatType = 0 + advancedFormat FormatType = 1 + simpleOldFormat FormatType = 2 + advancedOldFormat FormatType = 3 +) + +func decideFormat(b []byte) (FormatType, error) { + var raw map[string]interface{} + err := json.Unmarshal(b, &raw) + if err != nil { + return 0, err + } + + if raw["keys"] != nil { + switch raw["keys"].(type) { + case string: + return simpleOldFormat, nil + default: + return advancedOldFormat, nil + } + } + + switch raw["key"].(type) { + case string: + return simpleFormat, nil + default: + return advancedFormat, nil + } +} + func (j *jsonAccount) UnmarshalJSON(b []byte) error { - fmt.Println("IN", string(b)) + format, err := decideFormat(b) + if err != nil { + return err + } - // try simple old format - var simpleOld jsonAccountSimpleOld - err := json.Unmarshal(b, &simpleOld) - if err == nil { + switch format { + case simpleFormat: + var simple jsonAccountSimple + err = json.Unmarshal(b, &simple) + j.Simple = simple + + case advancedFormat: + var advanced jsonAccountAdvanced + err = json.Unmarshal(b, &advanced) + j.Advanced = advanced + + case simpleOldFormat: + var simpleOld jsonAccountSimpleOld + err = json.Unmarshal(b, &simpleOld) j.Simple = jsonAccountSimple{ Address: simpleOld.Address, Key: simpleOld.Keys, } - return nil - } - // try advanced old format - var advancedOld jsonAccountAdvancedOld - err = json.Unmarshal(b, &advancedOld) - if err == nil { + case advancedOldFormat: + var advancedOld jsonAccountAdvancedOld + err = json.Unmarshal(b, &advancedOld) j.Advanced = jsonAccountAdvanced{ Address: advancedOld.Address, Key: advancedOld.Keys[0], } - return nil - } - - // try simple format - var simple jsonAccountSimple - err = json.Unmarshal(b, &simple) - if err == nil { - j.Simple = simple - return nil - } - - // try advanced format - var advanced jsonAccountAdvanced - err = json.Unmarshal(b, &advanced) - if err == nil { - j.Advanced = advanced - return nil } - // TODO: better error handling - here we just return error from advanced case return err } From 4f58d9760124344278a4c32f3c20644ac915a27a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 20:59:44 +0200 Subject: [PATCH 083/171] add private key getter --- pkg/flowcli/project/keys.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/project/keys.go b/pkg/flowcli/project/keys.go index 313bd101b..3a161d885 100644 --- a/pkg/flowcli/project/keys.go +++ b/pkg/flowcli/project/keys.go @@ -40,6 +40,7 @@ type AccountKey interface { Signer(ctx context.Context) (crypto.Signer, error) ToConfig() config.AccountKey Validate() error + PrivateKey() (*crypto.PrivateKey, error) } func NewAccountKey(accountKeyConf config.AccountKey) (AccountKey, error) { @@ -129,6 +130,10 @@ func (a *KmsAccountKey) Validate() error { return util.GcloudApplicationSignin(resourceID) } +func (a *KmsAccountKey) PrivateKey() (*crypto.PrivateKey, error) { + return nil, fmt.Errorf("private key not accessible") +} + func newKmsAccountKey(key config.AccountKey) (AccountKey, error) { accountKMSKey, err := cloudkms.KeyFromResourceID(key.Context[config.KMSContextField]) if err != nil { @@ -188,8 +193,8 @@ func (a *HexAccountKey) Signer(ctx context.Context) (crypto.Signer, error) { return crypto.NewInMemorySigner(a.privateKey, a.HashAlgo()), nil } -func (a *HexAccountKey) PrivateKey() crypto.PrivateKey { - return a.privateKey +func (a *HexAccountKey) PrivateKey() (*crypto.PrivateKey, error) { + return &a.privateKey, nil } func (a *HexAccountKey) ToConfig() config.AccountKey { @@ -204,6 +209,15 @@ func (a *HexAccountKey) ToConfig() config.AccountKey { } } +func (a *HexAccountKey) Validate() error { + _, err := crypto.DecodePrivateKeyHex(a.sigAlgo, a.PrivateKeyHex()) + if err != nil { + return fmt.Errorf("invalid private key") + } + + return nil +} + func (a *HexAccountKey) PrivateKeyHex() string { return hex.EncodeToString(a.privateKey.Encode()) } From 557b013b88b126ee61cdc4999e54373f17632a31 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 21 Apr 2021 20:59:53 +0200 Subject: [PATCH 084/171] refactor private key --- internal/emulator/start.go | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/internal/emulator/start.go b/internal/emulator/start.go index 1d923f8f6..9d1b7eb7b 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -77,23 +77,22 @@ func ConfiguredServiceKey( } } - serviceAccount, _ := proj.EmulatorServiceAccount() + serviceAccount, err := proj.EmulatorServiceAccount() + if err != nil { + util.Exit(1, err.Error()) + } - serviceKeyHex, ok := serviceAccount.Key().(*project.HexAccountKey) - if !ok { + privateKey, err := serviceAccount.Key().PrivateKey() + if err != nil { util.Exit(1, "Only hexadecimal keys can be used as the emulator service account key.") } - privateKey, err := crypto.DecodePrivateKeyHex(serviceKeyHex.SigAlgo(), serviceKeyHex.PrivateKeyHex()) + err = serviceAccount.Key().Validate() if err != nil { - util.Exitf( - 1, - "Invalid private key in \"%s\" emulator configuration", - config.DefaultEmulatorConfigName, - ) + util.Exit(1, err.Error()) } - return privateKey, serviceKeyHex.SigAlgo(), serviceKeyHex.HashAlgo() + return *privateKey, serviceAccount.Key().SigAlgo(), serviceAccount.Key().HashAlgo() } func init() { From abb44604bf211b53534f01e93fc62640c05c31bd Mon Sep 17 00:00:00 2001 From: Greg <75445744+sideninja@users.noreply.github.com> Date: Thu, 22 Apr 2021 10:57:55 +0200 Subject: [PATCH 085/171] Update internal/command/command.go Co-authored-by: Peter Siemens --- internal/command/command.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index 0f54067c8..69745904a 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -234,11 +234,13 @@ func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (st } networks := config.DefaultNetworks() - if networks.GetByName(networkFlag) != nil { - return networks.GetByName(networkFlag).Host, nil - } else { - return "", fmt.Errorf("invalid network with name %s", networkFlag) + network := networks.GetByName(networkFlag) + + if network != nil { + return network.Host, nil } + + return "", fmt.Errorf("invalid network with name %s", networkFlag) } // create logger utility From 01e12226ad28b52937ca0e0c5dd00acba5776a4a Mon Sep 17 00:00:00 2001 From: Greg <75445744+sideninja@users.noreply.github.com> Date: Thu, 22 Apr 2021 10:58:16 +0200 Subject: [PATCH 086/171] Update docs/security.md Co-authored-by: Peter Siemens --- docs/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/security.md b/docs/security.md index c718aac73..2bad2eb2e 100644 --- a/docs/security.md +++ b/docs/security.md @@ -76,7 +76,7 @@ PRIVATE_KEY=key flow project deploy } ``` -### Private Environment File +### Private Dotenv File Setting environment variables can be avoided by using environment file `.env`. Anything you put in `.env` file will be loaded as environment variable and replaced in configuration the From 8cdcbf1cfaaa689fdd9e351010607b26e66ad103 Mon Sep 17 00:00:00 2001 From: Greg <75445744+sideninja@users.noreply.github.com> Date: Thu, 22 Apr 2021 10:58:43 +0200 Subject: [PATCH 087/171] Update docs/security.md Co-authored-by: Peter Siemens --- docs/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/security.md b/docs/security.md index 2bad2eb2e..a00bdf250 100644 --- a/docs/security.md +++ b/docs/security.md @@ -82,7 +82,7 @@ Setting environment variables can be avoided by using environment file `.env`. A you put in `.env` file will be loaded as environment variable and replaced in configuration the same way as environment variable. -⚠️ Please be sure to add `.env` file to `.gitignore` +⚠️ You should never commit `.env` to source control, especially if it contains sensitive information like a private key. Example `.env` file: ```bash From 1b7e545854d81dc75653a5253413b01b95c00f1c Mon Sep 17 00:00:00 2001 From: Greg <75445744+sideninja@users.noreply.github.com> Date: Thu, 22 Apr 2021 10:59:51 +0200 Subject: [PATCH 088/171] Update docs/security.md --- docs/security.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/security.md b/docs/security.md index a00bdf250..936272f71 100644 --- a/docs/security.md +++ b/docs/security.md @@ -78,9 +78,7 @@ PRIVATE_KEY=key flow project deploy ### Private Dotenv File -Setting environment variables can be avoided by using environment file `.env`. Anything -you put in `.env` file will be loaded as environment variable and replaced in configuration the -same way as environment variable. +The CLI will load environment variables defined a .env file in the active directory, if one exists. These variables can be substituted inside flow.json, just like any other environment variable. ⚠️ You should never commit `.env` to source control, especially if it contains sensitive information like a private key. From 478ef11a1b30b1c54433f68e8af926b3dfe2cc6e Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 11:30:00 +0200 Subject: [PATCH 089/171] refactor save default --- internal/emulator/start.go | 2 +- pkg/flowcli/project/project.go | 13 +++++++++---- pkg/flowcli/services/project.go | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/internal/emulator/start.go b/internal/emulator/start.go index 9d1b7eb7b..ed432ff90 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -61,7 +61,7 @@ func ConfiguredServiceKey( if err != nil { util.Exitf(1, err.Error()) } else { - err = proj.Save(project.DefaultConfigPath) + err = proj.SaveDefault() if err != nil { util.Exitf(1, err.Error()) } diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index b6ac99acb..8bbd1c9e8 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -56,11 +56,11 @@ type Contract struct { // Load loads a project configuration and returns the resulting project. func Load(configFilePath []string) (*Project, error) { - composer := config.NewLoader(afero.NewOsFs()) + loader := config.NewLoader(afero.NewOsFs()) // here we add all available parsers (more to add yaml etc...) - composer.AddConfigParser(json.NewParser()) - conf, err := composer.Load(configFilePath) + loader.AddConfigParser(json.NewParser()) + conf, err := loader.Load(configFilePath) if err != nil { if errors.Is(err, config.ErrDoesNotExist) { @@ -70,7 +70,7 @@ func Load(configFilePath []string) (*Project, error) { return nil, err } - proj, err := newProject(conf, composer) + proj, err := newProject(conf, loader) if err != nil { return nil, fmt.Errorf("invalid project configuration: %s", err) } @@ -78,6 +78,11 @@ func Load(configFilePath []string) (*Project, error) { return proj, nil } +// SaveDefault saves configuration to default path +func (p *Project) SaveDefault() error { + return p.Save(DefaultConfigPath) +} + // Save saves the project configuration to the given path. func (p *Project) Save(path string) error { p.conf.Accounts = accountsToConfig(p.accounts) diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index f3a6683ab..e6f5b274b 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -83,7 +83,7 @@ func (p *Project) Init( proj.SetEmulatorServiceKey(serviceKey) } - err = proj.Save(project.DefaultConfigPath) + err = proj.SaveDefault() if err != nil { return nil, err } From e9beb3b56b5f61e9740c1792312eb47baddc7f74 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 20:59:11 +0200 Subject: [PATCH 090/171] add command for config --- internal/config/add.go | 116 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 internal/config/add.go diff --git a/internal/config/add.go b/internal/config/add.go new file mode 100644 index 000000000..3211d3d49 --- /dev/null +++ b/internal/config/add.go @@ -0,0 +1,116 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsAdd struct{} + +var addFlags = flagsAdd{} + +var AddCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "add ", + Short: "Add resource to configuration", + Example: "flow config add account", + ValidArgs: []string{"account", "contract", "deployment", "network"}, + Args: cobra.ExactArgs(1), + }, + Flags: &addFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + resource := args[0] + + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + + conf := p.Config() + + switch resource { + case "account": + accountData := output.NewAccountPrompt() + account, err := config.StringToAccount( + accountData["name"], + accountData["address"], + accountData["keyIndex"], + accountData["sigAlgo"], + accountData["hashAlgo"], + accountData["key"], + ) + if err != nil { + return nil, err + } + + err = services.Config.AddAccount(*account) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "account added", + }, nil + + case "contract": + contractData := output.NewContractPrompt() + contracts := config.StringToContracts( + contractData["name"], + contractData["source"], + contractData["emulator"], + contractData["testnet"], + ) + + err := services.Config.AddContracts(contracts) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "contract added", + }, nil + + case "deployment": + deployData := output.NewDeploymentPrompt(conf) + deployment := config.StringToDeployment( + deployData["network"].(string), + deployData["account"].(string), + deployData["contracts"].([]string), + ) + err := services.Config.AddDeployment(deployment) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "deploy added", + }, nil + + case "network": + networkData := output.NewNetworkPrompt() + network := config.StringToNetwork(networkData["name"], networkData["host"]) + + err := services.Config.AddNetwork(network) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "network added", + }, nil + } + + return nil, nil + }, +} From e1005a684cc5e0af92068b0d784cd2d6606ba472 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 20:59:22 +0200 Subject: [PATCH 091/171] config top command added --- internal/config/config.go | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 internal/config/config.go diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 000000000..614757cf5 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,39 @@ +package config + +import ( + "github.com/spf13/cobra" +) + +var Cmd = &cobra.Command{ + Use: "config", + Short: "Utilities to manage configuration", + TraverseChildren: true, +} + +func init() { + //InitCommand.AddToParent(Cmd) + AddCommand.AddToParent(Cmd) +} + +// configResult result from configuration +type ConfigResult struct { + result string +} + +// JSON convert result to JSON +func (r *ConfigResult) JSON() interface{} { + return nil +} + +func (r *ConfigResult) String() string { + if r.result != "" { + return r.result + } + + return "" +} + +// Oneliner show result as one liner grep friendly +func (r *ConfigResult) Oneliner() string { + return "" +} From 46345fbb4b09b3f96dca298e323e450dc3c155aa Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 20:59:45 +0200 Subject: [PATCH 092/171] config service wip --- pkg/flowcli/services/config.go | 104 +++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 pkg/flowcli/services/config.go diff --git a/pkg/flowcli/services/config.go b/pkg/flowcli/services/config.go new file mode 100644 index 000000000..99ddd6464 --- /dev/null +++ b/pkg/flowcli/services/config.go @@ -0,0 +1,104 @@ +package services + +import ( + "fmt" + + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli/gateway" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" +) + +// Accounts is a service that handles all account-related interactions. +type Config struct { + gateway gateway.Gateway + project *project.Project + logger output.Logger +} + +// NewAccounts returns a new accounts service. +func NewConfig( + gateway gateway.Gateway, + project *project.Project, + logger output.Logger, +) *Config { + return &Config{ + gateway: gateway, + project: project, + logger: logger, + } +} + +func (c *Config) AddAccount(account config.Account) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + + c.project.Config().Accounts.AddOrUpdate(account.Name, account) + + return c.project.SaveDefault() +} + +func (c *Config) RemoveAccount(name string) { + +} + +func (c *Config) AddContracts(contracts []config.Contract) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + + for _, contract := range contracts { + c.project.Config().Contracts.AddOrUpdate(contract.Name, contract) + } + + return c.project.SaveDefault() +} + +func (c *Config) RemoveContract(name string) { + +} + +func (c *Config) AddNetwork(network config.Network) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + + c.project.Config().Networks.AddOrUpdate(network.Name, network) + + return c.project.SaveDefault() +} + +func (c *Config) RemoveNetwork(name string) { + +} + +func (c *Config) AddDeployment(deployment config.Deploy) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + + c.project.Config().Deployments.AddOrUpdate(deployment) + + return c.project.SaveDefault() +} + +func (c *Config) RemoveDeployment(name string) { + +} + +func (c *Config) ListDeployments() { + +} + +func (c *Config) ListAccounts() { + +} + +func (c *Config) ListNetworks() { + +} + +func (c *Config) ListContracts() { + +} From a5766f8458a8d48a67f884bc40ab809f2a86d2e1 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 20:59:54 +0200 Subject: [PATCH 093/171] add conf command --- cmd/flow/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 93cbf7f6c..22a0dc458 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -59,6 +59,7 @@ func main() { cmd.AddCommand(blocks.Cmd) cmd.AddCommand(collections.Cmd) cmd.AddCommand(project.Cmd) + cmd.AddCommand(config.Cmd) command.InitFlags(cmd) From 76adb512218ec73b74a25e23d15e494daeeb8c35 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 21:00:03 +0200 Subject: [PATCH 094/171] add parsers --- pkg/flowcli/config/parsers.go | 162 ++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 pkg/flowcli/config/parsers.go diff --git a/pkg/flowcli/config/parsers.go b/pkg/flowcli/config/parsers.go new file mode 100644 index 000000000..119d32fb7 --- /dev/null +++ b/pkg/flowcli/config/parsers.go @@ -0,0 +1,162 @@ +package config + +import ( + "fmt" + "strconv" + + "github.com/onflow/flow-go-sdk/crypto" + + "github.com/onflow/flow-go-sdk" +) + +// StringToAccount converts string values to account +func StringToAccount( + name string, + address string, + index string, + sigAlgo string, + hashAlgo string, + key string, +) (*Account, error) { + parsedAddress, err := StringToAddress(address) + if err != nil { + return nil, err + } + + parsedIndex, err := StringToKeyIndex(index) + if err != nil { + return nil, err + } + + parsedKey, err := StringToHexKey(key, sigAlgo) + if err != nil { + return nil, err + } + + accountKey := AccountKey{ + Type: KeyTypeHex, + Index: parsedIndex, + SigAlgo: crypto.StringToSignatureAlgorithm(sigAlgo), + HashAlgo: crypto.StringToHashAlgorithm(hashAlgo), + Context: map[string]string{ + PrivateKeyField: parsedKey.String(), + }, + } + + return &Account{ + Name: name, + Address: *parsedAddress, + Key: accountKey, + }, nil +} + +func StringToKeyIndex(value string) (int, error) { + v, err := strconv.Atoi(value) + if err != nil { + return 0, fmt.Errorf("invalid index, must be a number") + } + if v < 0 { + return 0, fmt.Errorf("invalid index, must be positive") + } + + return v, nil +} + +func StringToAddress(value string) (*flow.Address, error) { + address := flow.HexToAddress(value) + + if !address.IsValid(flow.Mainnet) && + !address.IsValid(flow.Testnet) && + !address.IsValid(flow.Emulator) { + return nil, fmt.Errorf("invalid address") + } + + return &address, nil +} + +func StringToHexKey(key string, sigAlgo string) (*crypto.PrivateKey, error) { + privateKey, err := crypto.DecodePrivateKeyHex( + crypto.StringToSignatureAlgorithm(sigAlgo), + key, + ) + if err != nil { + return nil, err + } + + return &privateKey, nil +} + +func StringToContracts( + name string, + source string, + emulatorAlias string, + testnetAlias string, +) []Contract { + contracts := make([]Contract, 0) + + if emulatorAlias != "" { + contracts = append(contracts, Contract{ + Name: name, + Source: source, + Network: DefaultEmulatorNetwork().Name, + Alias: emulatorAlias, + }) + } + + if testnetAlias != "" { + contracts = append(contracts, Contract{ + Name: name, + Source: source, + Network: DefaultTestnetNetwork().Name, + Alias: testnetAlias, + }) + } + + if emulatorAlias == "" && testnetAlias == "" { + contracts = append(contracts, Contract{ + Name: name, + Source: source, + Network: "", + Alias: "", + }) + } + + return contracts +} + +func StringToNetwork(name string, host string) Network { + return Network{ + Name: name, + Host: host, + } +} + +func StringToDeployment(network string, account string, contracts []string) Deploy { + parsedContracts := make([]ContractDeployment, 0) + + for _, c := range contracts { + // prevent adding multiple contracts with same name + exists := false + for _, p := range parsedContracts { + if p.Name == c { + exists = true + } + } + if exists { + continue + } + + parsedContracts = append( + parsedContracts, + ContractDeployment{ + Name: c, + Args: nil, + }) + } + + return Deploy{ + Network: network, + Account: account, + Contracts: parsedContracts, + } +} From eab72753e7ccbbe91f0c97895b894857f61a4cde Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 21:00:23 +0200 Subject: [PATCH 095/171] rename getter --- pkg/flowcli/services/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index e6f5b274b..f57f6fd7c 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -110,7 +110,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er ) // add all contracts needed to deploy to processor - contractsNetwork, err := p.project.ContractsByNetwork(network) + contractsNetwork, err := p.project.DeploymentContractsByNetwork(network) if err != nil { return nil, err } From 32a2f9821754a6a32e88d4787d1bd1f0cefda9b2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 21:00:51 +0200 Subject: [PATCH 096/171] add prompts for adding config --- pkg/flowcli/output/prompt.go | 205 +++++++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index efe94623e..e3db38651 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -20,6 +20,11 @@ package output import ( "fmt" + "net/url" + + "github.com/onflow/flow-cli/pkg/flowcli/util" + + "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/gosuri/uilive" "github.com/manifoldco/promptui" @@ -91,3 +96,203 @@ func ApproveTransactionPrompt(transaction *project.Transaction) bool { return result == "Yes" } + +func namePrompt() string { + namePrompt := promptui.Prompt{ + Label: "Name", + Validate: func(s string) error { + if len(s) < 1 { + return fmt.Errorf("invalid name") + } + return nil + }, + } + + name, _ := namePrompt.Run() + return name +} + +func addressPrompt() string { + addressPrompt := promptui.Prompt{ + Label: "Address", + Validate: func(s string) error { + _, err := config.StringToAddress(s) + return err + }, + } + + address, _ := addressPrompt.Run() + return address +} + +func contractAliasPrompt(contractName string) (string, string) { + networks := []string{"emulator", "testnet"} + + aliasesPrompt := promptui.Select{ + Label: fmt.Sprintf( + "Does contract [%s] have any additional aliases: \nYou can read about aliases here: https://docs.onflow.org/flow-cli/project-contracts/", // todo check + contractName, + ), + Items: []string{"No", "Yes, Emulator Alias", "Yes, Testnet Alias"}, + } + i, answer, _ := aliasesPrompt.Run() + return answer, networks[i] +} + +func contractPrompt(contractNames []string) string { + contractPrompt := promptui.Select{ + Label: "Choose contract you wish to deploy", + Items: contractNames, + } + _, contractName, _ := contractPrompt.Run() + + return contractName +} + +func addAnotherContractToDeploymentPrompt() bool { + addContractPrompt := promptui.Select{ + Label: "Do you wish to add another contract for deployment?", + Items: []string{"No", "Yes"}, + } + _, addMore, _ := addContractPrompt.Run() + return addMore == "Yes" +} + +func NewAccountPrompt() map[string]string { + accountData := make(map[string]string) + + accountData["name"] = namePrompt() + accountData["address"] = addressPrompt() + + sigAlgoPrompt := promptui.Select{ + Label: "Signature algorithm", + Items: []string{"ECDSA_P256", "ECDSA_secp256k1"}, + } + _, accountData["sigAlgo"], _ = sigAlgoPrompt.Run() + + hashAlgoPrompt := promptui.Select{ + Label: "Hashing algorithm", + Items: []string{"SHA3_256", "SHA2_256"}, + } + _, accountData["hashAlgo"], _ = hashAlgoPrompt.Run() + + keyPrompt := promptui.Prompt{ + Label: "Private key", + Validate: func(s string) error { + _, err := config.StringToHexKey(s, accountData["sigAlgo"]) + return err + }, + } + accountData["key"], _ = keyPrompt.Run() + + keyIndexPrompt := promptui.Prompt{ + Label: "Key index (Default: 0)", + Default: "0", + Validate: func(s string) error { + _, err := config.StringToKeyIndex(s) + return err + }, + } + accountData["keyIndex"], _ = keyIndexPrompt.Run() + + return accountData +} + +func NewContractPrompt() map[string]string { + contractData := make(map[string]string) + + contractData["name"] = namePrompt() + + sourcePrompt := promptui.Prompt{ + Label: "Contract file location", + Validate: func(s string) error { + if !config.Exists(s) { + return fmt.Errorf("contract file doesn't exist: %s", s) + } + + return nil + }, + } + contractData["source"], _ = sourcePrompt.Run() + + aliasAnswer, network := contractAliasPrompt(contractData["name"]) + for aliasAnswer != "No" { + aliasAddress := addressPrompt() + contractData[network] = aliasAddress + + aliasAnswer, network = contractAliasPrompt(contractData["name"]) + } + + return contractData +} + +func NewNetworkPrompt() map[string]string { + networkData := make(map[string]string) + networkData["name"] = namePrompt() + + hostPrompt := promptui.Prompt{ + Label: "Enter host location", + Validate: func(s string) error { + _, err := url.ParseRequestURI(s) + return err + }, + } + networkData["host"], _ = hostPrompt.Run() + + return networkData +} + +func NewDeploymentPrompt(conf *config.Config) map[string]interface{} { + deploymentData := make(map[string]interface{}) + + networkNames := make([]string, 0) + for _, network := range conf.Networks { + networkNames = append(networkNames, network.Name) + } + + networkPrompt := promptui.Select{ + Label: "Choose network for deployment", + Items: networkNames, + } + _, deploymentData["network"], _ = networkPrompt.Run() + + accountNames := make([]string, 0) + for _, account := range conf.Accounts { + accountNames = append(accountNames, account.Name) + } + + accountPrompt := promptui.Select{ + Label: "Choose an account to deploy to", + Items: accountNames, + } + _, deploymentData["account"], _ = accountPrompt.Run() + + contractNames := make([]string, 0) + for _, contract := range conf.Contracts { + contractNames = append(contractNames, contract.Name) + } + + deploymentData["contracts"] = make([]string, 0) + + contractName := contractPrompt(contractNames) + deploymentData["contracts"] = append(deploymentData["contracts"].([]string), contractName) + contractNames = util.RemoveFromStringArray(contractNames, contractName) + + for addAnotherContractToDeploymentPrompt() { + contractName := contractPrompt(contractNames) + deploymentData["contracts"] = append(deploymentData["contracts"].([]string), contractName) + contractNames = util.RemoveFromStringArray(contractNames, contractName) + + if len(contractNames) == 0 { + break + } + } + + return deploymentData +} + +func RemoveAccountPrompt(conf *config.Config) { + + // list and remove + +} From e3dc6cc9b022cc7d596aafe1c9f81d070be7aa0a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 21:01:11 +0200 Subject: [PATCH 097/171] rename getter --- pkg/flowcli/services/scripts.go | 2 +- pkg/flowcli/services/transactions.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/services/scripts.go b/pkg/flowcli/services/scripts.go index 9aa72d5c3..e7a75ed95 100644 --- a/pkg/flowcli/services/scripts.go +++ b/pkg/flowcli/services/scripts.go @@ -88,7 +88,7 @@ func (s *Scripts) execute(code []byte, args []string, argsJSON string, scriptPat return nil, fmt.Errorf("resolving imports in scripts not supported") } - contractsNetwork, err := s.project.ContractsByNetwork(network) + contractsNetwork, err := s.project.DeploymentContractsByNetwork(network) if err != nil { return nil, err } diff --git a/pkg/flowcli/services/transactions.go b/pkg/flowcli/services/transactions.go index 4b1f14c52..fc8e400ac 100644 --- a/pkg/flowcli/services/transactions.go +++ b/pkg/flowcli/services/transactions.go @@ -145,7 +145,7 @@ func (t *Transactions) Build( return nil, fmt.Errorf("resolving imports in transactions not supported") } - contractsNetwork, err := t.project.ContractsByNetwork(network) + contractsNetwork, err := t.project.DeploymentContractsByNetwork(network) if err != nil { return nil, err } From f50a0af123155c9f9e7ab682c4e2f58c844f8fb2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 21:01:30 +0200 Subject: [PATCH 098/171] add config to cmd --- pkg/flowcli/services/services.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/flowcli/services/services.go b/pkg/flowcli/services/services.go index c93cf25aa..96d138b78 100644 --- a/pkg/flowcli/services/services.go +++ b/pkg/flowcli/services/services.go @@ -35,6 +35,7 @@ type Services struct { Collections *Collections Project *Project Blocks *Blocks + Config *Config } // NewServices returns a new services collection for a project, @@ -53,5 +54,6 @@ func NewServices( Collections: NewCollections(gateway, proj, logger), Project: NewProject(gateway, proj, logger), Blocks: NewBlocks(gateway, proj, logger), + Config: NewConfig(gateway, proj, logger), } } From 175db47a810675e447454f7f8944bdf1578fa5a5 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Thu, 22 Apr 2021 21:01:56 +0200 Subject: [PATCH 099/171] add config getter --- pkg/flowcli/project/project.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 8bbd1c9e8..da9668972 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -137,7 +137,7 @@ func newProject(conf *config.Config, composer *config.Loader) (*Project, error) // The CLI currently does not allow the same contract to be deployed to multiple // accounts in the same network. func (p *Project) ContractConflictExists(network string) bool { - contracts, err := p.ContractsByNetwork(network) + contracts, err := p.DeploymentContractsByNetwork(network) if err != nil { return false } @@ -160,6 +160,11 @@ func (p *Project) NetworkByName(name string) *config.Network { return p.conf.Networks.GetByName(name) } +// Config get project configuration +func (p *Project) Config() *config.Config { + return p.conf +} + // EmulatorServiceAccount returns the service account for the default emulator profilee. func (p *Project) EmulatorServiceAccount() (*Account, error) { emulator := p.conf.Emulators.Default() @@ -179,8 +184,8 @@ func (p *Project) SetEmulatorServiceKey(privateKey crypto.PrivateKey) { ) } -// ContractsByNetwork returns all contracts for a network. -func (p *Project) ContractsByNetwork(network string) ([]Contract, error) { +// DeploymentContractsByNetwork returns all contracts for a network. +func (p *Project) DeploymentContractsByNetwork(network string) ([]Contract, error) { contracts := make([]Contract, 0) // get deployments for the specified network From f6e0951eba0c22b4e21d671e75b7535a4ff9e398 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:21:19 +0200 Subject: [PATCH 100/171] remove command --- internal/config/remove.go | 87 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 internal/config/remove.go diff --git a/internal/config/remove.go b/internal/config/remove.go new file mode 100644 index 000000000..f9f0574ef --- /dev/null +++ b/internal/config/remove.go @@ -0,0 +1,87 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsRemove struct{} + +var removeFlags = flagsRemove{} + +var RemoveCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "remove ", + Short: "Remove resource from configuration", + Example: "flow config remove account", + ValidArgs: []string{"account", "contract", "deployment", "network"}, + Args: cobra.ExactArgs(1), + }, + Flags: &removeFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + resource := args[0] + + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + + switch resource { + case "account": + name := output.RemoveAccountPrompt(p.Config()) + err := services.Config.RemoveAccount(name) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "account removed", + }, nil + + case "deployment": + accountName, networkName := output.RemoveDeploymentPrompt(p.Config()) + err := services.Config.RemoveDeployment(accountName, networkName) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "deployment removed", + }, nil + + case "contract": + name := output.RemoveContractPrompt(p.Config()) + err := services.Config.RemoveContract(name) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "contract removed", + }, nil + + case "network": + name := output.RemoveNetworkPrompt(p.Config()) + err := services.Config.RemoveNetwork(name) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "network removed", + }, nil + } + + return nil, nil + }, +} From 4194ad037f51264bcef0ac71a20e0abd72f80150 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:21:38 +0200 Subject: [PATCH 101/171] remove functions --- pkg/flowcli/config/config.go | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 72ca130bb..1f24d47d8 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -20,6 +20,7 @@ package config import ( "errors" + "fmt" "github.com/onflow/cadence" @@ -240,6 +241,21 @@ func (c *Contracts) AddOrUpdate(name string, contract Contract) { *c = append(*c, contract) } +func (c *Contracts) Remove(name string) error { + contract := c.GetByName(name) + if contract == nil { + return fmt.Errorf("contract named %s does not exist in configuration", name) + } + + for i, contract := range *c { + if contract.Name == name { + *c = append((*c)[0:i], (*c)[i+1:]...) // remove item + } + } + + return nil +} + // AccountByName get account by name func (a *Accounts) GetByName(name string) *Account { for _, account := range *a { @@ -263,6 +279,22 @@ func (a *Accounts) AddOrUpdate(name string, account Account) { *a = append(*a, account) } +// Remove remove account by name +func (a *Accounts) Remove(name string) error { + account := a.GetByName(name) + if account == nil { + return fmt.Errorf("account named %s does not exist in configuration", name) + } + + for i, account := range *a { + if account.Name == name { + *a = append((*a)[0:i], (*a)[i+1:]...) // remove item + } + } + + return nil +} + // GetByNetwork get all deployments by network func (d *Deployments) GetByNetwork(network string) Deployments { var deployments Deployments @@ -301,6 +333,26 @@ func (d *Deployments) AddOrUpdate(deployment Deploy) { *d = append(*d, deployment) } +// Remove removes deployment by account and network +func (d *Deployments) Remove(account string, network string) error { + deployment := d.GetByAccountAndNetwork(account, network) + if deployment == nil { + return fmt.Errorf( + "deployment for account %s on network %s does not exist in configuration", + account, + network, + ) + } + + for i, deployment := range *d { + if deployment.Network == network && deployment.Account == account { + *d = append((*d)[0:i], (*d)[i+1:]...) // remove item + } + } + + return nil +} + // GetByName get network by name func (n *Networks) GetByName(name string) *Network { for _, network := range *n { @@ -324,6 +376,21 @@ func (n *Networks) AddOrUpdate(name string, network Network) { *n = append(*n, network) } +func (n *Networks) Remove(name string) error { + network := n.GetByName(name) + if network == nil { + return fmt.Errorf("network named %s does not exist in configuration", name) + } + + for i, network := range *n { + if network.Name == name { + *n = append((*n)[0:i], (*n)[i+1:]...) // remove item + } + } + + return nil +} + // Default gets default emulator func (e *Emulators) Default() *Emulator { for _, emulator := range *e { From 53397ce0a379c3e01f593f432ce9e5d20ca89e2a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:21:48 +0200 Subject: [PATCH 102/171] conf add remove command --- internal/config/config.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/config/config.go b/internal/config/config.go index 614757cf5..e22268ef5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -13,6 +13,7 @@ var Cmd = &cobra.Command{ func init() { //InitCommand.AddToParent(Cmd) AddCommand.AddToParent(Cmd) + RemoveCommand.AddToParent(Cmd) } // configResult result from configuration From 7b69de04bf180c11716019c2d6872c0f335a34cc Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:21:59 +0200 Subject: [PATCH 103/171] config service --- pkg/flowcli/services/config.go | 47 +++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/pkg/flowcli/services/config.go b/pkg/flowcli/services/config.go index 99ddd6464..e46dd5c7b 100644 --- a/pkg/flowcli/services/config.go +++ b/pkg/flowcli/services/config.go @@ -29,6 +29,8 @@ func NewConfig( } } +// TODO maybe this service layer is not needed + func (c *Config) AddAccount(account config.Account) error { if c.project == nil { return fmt.Errorf("missing configuration, initialize it: flow init") @@ -39,8 +41,18 @@ func (c *Config) AddAccount(account config.Account) error { return c.project.SaveDefault() } -func (c *Config) RemoveAccount(name string) { +// todo not removed as it is in config +func (c *Config) RemoveAccount(name string) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + err := c.project.Config().Accounts.Remove(name) + if err != nil { + return err + } + + return c.project.SaveDefault() } func (c *Config) AddContracts(contracts []config.Contract) error { @@ -55,8 +67,17 @@ func (c *Config) AddContracts(contracts []config.Contract) error { return c.project.SaveDefault() } -func (c *Config) RemoveContract(name string) { +func (c *Config) RemoveContract(name string) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + err := c.project.Config().Contracts.Remove(name) + if err != nil { + return err + } + + return c.project.SaveDefault() } func (c *Config) AddNetwork(network config.Network) error { @@ -69,8 +90,17 @@ func (c *Config) AddNetwork(network config.Network) error { return c.project.SaveDefault() } -func (c *Config) RemoveNetwork(name string) { +func (c *Config) RemoveNetwork(name string) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + err := c.project.Config().Networks.Remove(name) + if err != nil { + return err + } + + return c.project.SaveDefault() } func (c *Config) AddDeployment(deployment config.Deploy) error { @@ -83,8 +113,17 @@ func (c *Config) AddDeployment(deployment config.Deploy) error { return c.project.SaveDefault() } -func (c *Config) RemoveDeployment(name string) { +func (c *Config) RemoveDeployment(account string, network string) error { + if c.project == nil { + return fmt.Errorf("missing configuration, initialize it: flow init") + } + err := c.project.Config().Deployments.Remove(account, network) + if err != nil { + return err + } + + return c.project.SaveDefault() } func (c *Config) ListDeployments() { From eadb4c32be32749b1a70ff71ff0bd2d8a39f8210 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:22:08 +0200 Subject: [PATCH 104/171] add remove prompts --- pkg/flowcli/output/prompt.go | 77 +++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index e3db38651..fb8528986 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -291,8 +291,81 @@ func NewDeploymentPrompt(conf *config.Config) map[string]interface{} { return deploymentData } -func RemoveAccountPrompt(conf *config.Config) { +func RemoveAccountPrompt(conf *config.Config) string { + accountNames := make([]string, 0) + + for _, account := range conf.Accounts { + accountNames = append(accountNames, account.Name) + } + + namePrompt := promptui.Select{ + Label: "Select an account name you wish to remove", + Items: accountNames, + } + + _, name, _ := namePrompt.Run() + + return name +} - // list and remove +func RemoveDeploymentPrompt(conf *config.Config) (account string, network string) { + deploymentNames := make([]string, 0) + + for _, deployment := range conf.Deployments { + contractNames := make([]string, 0) + for _, c := range deployment.Contracts { + contractNames = append(contractNames, c.Name) + } + + deploymentNames = append( + deploymentNames, + fmt.Sprintf( + "Account: %s, Network: %s, Contracts: %s", + deployment.Account, + deployment.Network, + contractNames, + ), + ) + } + + deployPrompt := promptui.Select{ + Label: "Select deployment you wish to remove", + Items: deploymentNames, + } + + index, _, _ := deployPrompt.Run() + + return conf.Deployments[index].Account, conf.Deployments[index].Network +} + +func RemoveContractPrompt(conf *config.Config) string { + contractNames := make([]string, 0) + for _, contract := range conf.Contracts { + contractNames = append(contractNames, contract.Name) + } + + contractPrompt := promptui.Select{ + Label: "Select contract you wish to remove", + Items: contractNames, + } + + _, name, _ := contractPrompt.Run() + return name +} + +func RemoveNetworkPrompt(conf *config.Config) string { + networkNames := make([]string, 0) + + for _, network := range conf.Networks { + networkNames = append(networkNames, network.Name) + } + + networkPrompt := promptui.Select{ + Label: "Select network you wish to remove", + Items: networkNames, + } + + _, name, _ := networkPrompt.Run() + return name } From 8de98025cbafbebedb8085188c37596b25e2f05a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:22:16 +0200 Subject: [PATCH 105/171] utils --- pkg/flowcli/util/utilities.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pkg/flowcli/util/utilities.go b/pkg/flowcli/util/utilities.go index ab46ea7ba..058c8f88f 100644 --- a/pkg/flowcli/util/utilities.go +++ b/pkg/flowcli/util/utilities.go @@ -122,3 +122,14 @@ func ParseAddress(value string) (flow.Address, bool) { address.IsValid(flow.Testnet) || address.IsValid(flow.Emulator) } + +func RemoveFromStringArray(s []string, el string) []string { + for i, v := range s { + if v == el { + s = append(s[:i], s[i+1:]...) + break + } + } + + return s +} From bdec939582aa6bdaad5a1e8be37dd8fa3123bdc4 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:22:30 +0200 Subject: [PATCH 106/171] test fix --- pkg/flowcli/project/project_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/flowcli/project/project_test.go b/pkg/flowcli/project/project_test.go index 7b1185a64..08c4c7597 100644 --- a/pkg/flowcli/project/project_test.go +++ b/pkg/flowcli/project/project_test.go @@ -341,7 +341,7 @@ Project Tests func Test_GetContractsByNameSimple(t *testing.T) { p := generateSimpleProject() - contracts, _ := p.ContractsByNetwork("emulator") + contracts, _ := p.DeploymentContractsByNetwork("emulator") assert.Len(t, contracts, 1) assert.Equal(t, contracts[0].Name, "NonFungibleToken") @@ -383,7 +383,7 @@ func Test_HostSimple(t *testing.T) { func Test_GetContractsByNameComplex(t *testing.T) { p := generateComplexProject() - contracts, _ := p.ContractsByNetwork("emulator") + contracts, _ := p.DeploymentContractsByNetwork("emulator") assert.Equal(t, 7, len(contracts)) @@ -475,7 +475,7 @@ func Test_GetAliases(t *testing.T) { p := generateAliasesProject() aliases := p.AliasesForNetwork("emulator") - contracts, _ := p.ContractsByNetwork("emulator") + contracts, _ := p.DeploymentContractsByNetwork("emulator") assert.Len(t, aliases, 1) assert.Equal(t, aliases["../hungry-kitties/cadence/contracts/FungibleToken.cdc"], "ee82856bf20e2aa6") @@ -487,10 +487,10 @@ func Test_GetAliasesComplex(t *testing.T) { p := generateAliasesComplexProject() aEmulator := p.AliasesForNetwork("emulator") - cEmulator, _ := p.ContractsByNetwork("emulator") + cEmulator, _ := p.DeploymentContractsByNetwork("emulator") aTestnet := p.AliasesForNetwork("testnet") - cTestnet, _ := p.ContractsByNetwork("testnet") + cTestnet, _ := p.DeploymentContractsByNetwork("testnet") assert.Len(t, cEmulator, 1) assert.Equal(t, cEmulator[0].Name, "NonFungibleToken") From 5dd1d99f58c4cb29bee86db3039064432e405757 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 13:27:21 +0200 Subject: [PATCH 107/171] refactor passing conf to prompts --- internal/config/add.go | 3 +-- internal/config/remove.go | 9 +++++---- pkg/flowcli/output/prompt.go | 30 +++++++++++++++++------------- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/internal/config/add.go b/internal/config/add.go index 3211d3d49..abac42658 100644 --- a/internal/config/add.go +++ b/internal/config/add.go @@ -36,7 +36,6 @@ var AddCommand = &command.Command{ if err != nil { return nil, fmt.Errorf("configuration does not exists") } - conf := p.Config() switch resource { @@ -82,7 +81,7 @@ var AddCommand = &command.Command{ }, nil case "deployment": - deployData := output.NewDeploymentPrompt(conf) + deployData := output.NewDeploymentPrompt(conf.Networks, conf.Accounts, conf.Contracts) deployment := config.StringToDeployment( deployData["network"].(string), deployData["account"].(string), diff --git a/internal/config/remove.go b/internal/config/remove.go index f9f0574ef..bab239570 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -35,10 +35,11 @@ var RemoveCommand = &command.Command{ if err != nil { return nil, fmt.Errorf("configuration does not exists") } + conf := p.Config() switch resource { case "account": - name := output.RemoveAccountPrompt(p.Config()) + name := output.RemoveAccountPrompt(conf.Accounts) err := services.Config.RemoveAccount(name) if err != nil { return nil, err @@ -49,7 +50,7 @@ var RemoveCommand = &command.Command{ }, nil case "deployment": - accountName, networkName := output.RemoveDeploymentPrompt(p.Config()) + accountName, networkName := output.RemoveDeploymentPrompt(conf.Deployments) err := services.Config.RemoveDeployment(accountName, networkName) if err != nil { return nil, err @@ -60,7 +61,7 @@ var RemoveCommand = &command.Command{ }, nil case "contract": - name := output.RemoveContractPrompt(p.Config()) + name := output.RemoveContractPrompt(conf.Contracts) err := services.Config.RemoveContract(name) if err != nil { return nil, err @@ -71,7 +72,7 @@ var RemoveCommand = &command.Command{ }, nil case "network": - name := output.RemoveNetworkPrompt(p.Config()) + name := output.RemoveNetworkPrompt(conf.Networks) err := services.Config.RemoveNetwork(name) if err != nil { return nil, err diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index fb8528986..887d13f5f 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -242,11 +242,15 @@ func NewNetworkPrompt() map[string]string { return networkData } -func NewDeploymentPrompt(conf *config.Config) map[string]interface{} { +func NewDeploymentPrompt( + networks config.Networks, + accounts config.Accounts, + contracts config.Contracts, +) map[string]interface{} { deploymentData := make(map[string]interface{}) networkNames := make([]string, 0) - for _, network := range conf.Networks { + for _, network := range networks { networkNames = append(networkNames, network.Name) } @@ -257,7 +261,7 @@ func NewDeploymentPrompt(conf *config.Config) map[string]interface{} { _, deploymentData["network"], _ = networkPrompt.Run() accountNames := make([]string, 0) - for _, account := range conf.Accounts { + for _, account := range accounts { accountNames = append(accountNames, account.Name) } @@ -268,7 +272,7 @@ func NewDeploymentPrompt(conf *config.Config) map[string]interface{} { _, deploymentData["account"], _ = accountPrompt.Run() contractNames := make([]string, 0) - for _, contract := range conf.Contracts { + for _, contract := range contracts { contractNames = append(contractNames, contract.Name) } @@ -291,10 +295,10 @@ func NewDeploymentPrompt(conf *config.Config) map[string]interface{} { return deploymentData } -func RemoveAccountPrompt(conf *config.Config) string { +func RemoveAccountPrompt(accounts config.Accounts) string { accountNames := make([]string, 0) - for _, account := range conf.Accounts { + for _, account := range accounts { accountNames = append(accountNames, account.Name) } @@ -308,10 +312,10 @@ func RemoveAccountPrompt(conf *config.Config) string { return name } -func RemoveDeploymentPrompt(conf *config.Config) (account string, network string) { +func RemoveDeploymentPrompt(deployments config.Deployments) (account string, network string) { deploymentNames := make([]string, 0) - for _, deployment := range conf.Deployments { + for _, deployment := range deployments { contractNames := make([]string, 0) for _, c := range deployment.Contracts { contractNames = append(contractNames, c.Name) @@ -335,13 +339,13 @@ func RemoveDeploymentPrompt(conf *config.Config) (account string, network string index, _, _ := deployPrompt.Run() - return conf.Deployments[index].Account, conf.Deployments[index].Network + return deployments[index].Account, deployments[index].Network } -func RemoveContractPrompt(conf *config.Config) string { +func RemoveContractPrompt(contracts config.Contracts) string { contractNames := make([]string, 0) - for _, contract := range conf.Contracts { + for _, contract := range contracts { contractNames = append(contractNames, contract.Name) } @@ -354,10 +358,10 @@ func RemoveContractPrompt(conf *config.Config) string { return name } -func RemoveNetworkPrompt(conf *config.Config) string { +func RemoveNetworkPrompt(networks config.Networks) string { networkNames := make([]string, 0) - for _, network := range conf.Networks { + for _, network := range networks { networkNames = append(networkNames, network.Name) } From bc4f46a423db060b1c3cd70f08f836b0af7799f8 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 23 Apr 2021 19:13:23 +0200 Subject: [PATCH 108/171] wip --- internal/config/account.go | 20 ++++++++++++++++++++ internal/config/add.go | 2 +- pkg/flowcli/services/config.go | 16 ---------------- 3 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 internal/config/account.go diff --git a/internal/config/account.go b/internal/config/account.go new file mode 100644 index 000000000..1f94a0e17 --- /dev/null +++ b/internal/config/account.go @@ -0,0 +1,20 @@ +package config + +import ( + "github.com/onflow/flow-cli/internal/command" + "github.com/spf13/cobra" +) + +type flagsAccount struct{} + +var accountFlags = flagsAccount{} + +var AccountCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "add account", + Short: "Add resource to configuration", + Example: "flow config add account", + ValidArgs: []string{"account", "contract", "deployment", "network"}, + Args: cobra.ExactArgs(1), + }, +} diff --git a/internal/config/add.go b/internal/config/add.go index abac42658..d0e08b69e 100644 --- a/internal/config/add.go +++ b/internal/config/add.go @@ -17,7 +17,7 @@ var addFlags = flagsAdd{} var AddCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "add ", + Use: "add account", Short: "Add resource to configuration", Example: "flow config add account", ValidArgs: []string{"account", "contract", "deployment", "network"}, diff --git a/pkg/flowcli/services/config.go b/pkg/flowcli/services/config.go index e46dd5c7b..1234d013e 100644 --- a/pkg/flowcli/services/config.go +++ b/pkg/flowcli/services/config.go @@ -125,19 +125,3 @@ func (c *Config) RemoveDeployment(account string, network string) error { return c.project.SaveDefault() } - -func (c *Config) ListDeployments() { - -} - -func (c *Config) ListAccounts() { - -} - -func (c *Config) ListNetworks() { - -} - -func (c *Config) ListContracts() { - -} From 9e88c6b50f628ac3f51d64770d165fdfe4a036f3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Sat, 24 Apr 2021 15:22:21 +0200 Subject: [PATCH 109/171] merge fixes --- go.mod | 2 +- go.sum | 32 ++++++++++++++++++++++----- internal/transactions/transactions.go | 5 ++--- pkg/flowcli/project/account.go | 2 -- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index adb09819a..f53e9558a 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/a8m/envsubst v1.2.0 github.com/fatih/color v1.7.0 github.com/gosuri/uilive v0.0.4 - github.com/joho/godotenv v1.3.0 // indirect + github.com/joho/godotenv v1.3.0 github.com/magiconair/properties v1.8.1 // indirect github.com/manifoldco/promptui v0.8.0 github.com/onflow/cadence v0.14.4 diff --git a/go.sum b/go.sum index c15688bf5..fba001cb1 100644 --- a/go.sum +++ b/go.sum @@ -128,6 +128,7 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= @@ -187,6 +188,7 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg= github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -413,6 +415,8 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/bitset v1.0.0 h1:Ws0PXV3PwXqWK2n7Vz6idCdrV/9OrBXgHEJi27ZB9Dw= @@ -426,6 +430,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= @@ -443,10 +449,8 @@ github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfo github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -600,6 +604,8 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/m4ksio/wal v1.0.0 h1:PucHOZPz58BgWowe+Gf+gZUbgEdd4zFx+He45SGkHG0= github.com/m4ksio/wal v1.0.0/go.mod h1:S3UyatBTuMdoI5QTuz2DWb8Csd9568vYrFAmMI/bnMw= @@ -607,6 +613,8 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo= +github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -732,26 +740,41 @@ github.com/onflow/cadence v0.13.5-no-id-caching/go.mod h1:EEXKRNuW5C2E1wRM4fLhfq github.com/onflow/cadence v0.13.6/go.mod h1:EEXKRNuW5C2E1wRM4fLhfqoTgXohPFieXwOGJubz1Jg= github.com/onflow/cadence v0.13.7 h1:y+ftev0THtmq6etDsiNMQMVlUiF5SeplUNKXSAH9vZ8= github.com/onflow/cadence v0.13.7/go.mod h1:EEXKRNuW5C2E1wRM4fLhfqoTgXohPFieXwOGJubz1Jg= +github.com/onflow/cadence v0.14.2/go.mod h1:EEXKRNuW5C2E1wRM4fLhfqoTgXohPFieXwOGJubz1Jg= +github.com/onflow/cadence v0.14.4 h1:l5HQTGEcbPXZQEjIB0kFxVI8OmBgNHujLKAMSs/JvEQ= +github.com/onflow/cadence v0.14.4/go.mod h1:Jzno1fQNpJB16RUiodjAN4QuwuMC0dt8cLtjcxp+iI4= github.com/onflow/cadence/languageserver v0.13.1 h1:xJKxgEEXsC0GtiP0KtkWxNafpxpj1IQfa51uOIea6yg= github.com/onflow/cadence/languageserver v0.13.1/go.mod h1:o/GvA3BNLf8D30nmHweIBxH6zb5WWux9y9I8mqL5V1Q= +github.com/onflow/cadence/languageserver v0.14.4 h1:VoUnkFxwzFMJarjgK+xdum1Qw6WZY5niUhuwsnAc+5A= +github.com/onflow/cadence/languageserver v0.14.4/go.mod h1:j0SY6m5/9+/ldm/rP3LvJtKcPfe2hVoozJMx1nZfyC0= github.com/onflow/flow-core-contracts/lib/go/contracts v0.7.1 h1:nmIDPf94F9Ecx6ecGyd4uYBUl4LluntWLvtwAJYt4tw= github.com/onflow/flow-core-contracts/lib/go/contracts v0.7.1/go.mod h1:4zE/4A+5zyahxSFccQmcBqzp4ONXIwvGHaOKN8h8CRM= +github.com/onflow/flow-core-contracts/lib/go/templates v0.6.0 h1:2v10ZSCE4e3TyeDQvKplGJ4/d0X/+xgU2NmeXRmFYRw= +github.com/onflow/flow-core-contracts/lib/go/templates v0.6.0/go.mod h1:fLJbjGUHrlHdrjaeRDgKG9nZJ6spiCScc+Q5SARgH38= github.com/onflow/flow-core-contracts/lib/go/templates v0.7.1 h1:zayfufgOQcn/KtLIkaNEBYMr8nUuhNj+DSCMS1JRsUI= github.com/onflow/flow-core-contracts/lib/go/templates v0.7.1/go.mod h1:fLJbjGUHrlHdrjaeRDgKG9nZJ6spiCScc+Q5SARgH38= github.com/onflow/flow-emulator v0.16.1 h1:4p4R+Ub3Ae07j6rKSEjepl3MyI9bl2dQgIjclyj41W0= github.com/onflow/flow-emulator v0.16.1/go.mod h1:mWLZGYRFqEd8CRvbT16bIxqjAt9sqdZDyHJmjJSDVtU= +github.com/onflow/flow-emulator v0.17.0 h1:Hzf7rlDT5Ukyxz0PwyNHjbb2qhXRm7bHJ4IeSmHW8Dk= +github.com/onflow/flow-emulator v0.17.0/go.mod h1:pTBSEDxuN1YP3c/Xv/KXgJToPZW/0kkCYfVpJRSPOIs= github.com/onflow/flow-ft/lib/go/contracts v0.4.0 h1:M1I4z027GHOLcjkj9lL2UUUpZpEAF90hY5gRqvFGAPg= github.com/onflow/flow-ft/lib/go/contracts v0.4.0/go.mod h1:1zoTjp1KzNnOPkyqKmWKerUyf0gciw+e6tAEt0Ks3JE= github.com/onflow/flow-go v0.14.9 h1:yfyvEWWXJ+66mtTf/pEDPO3hwBKaQh06WVuvAXN7Vao= github.com/onflow/flow-go v0.14.9/go.mod h1:EGaieLf+gZ/HGci8HEHxh6VeES9Sfpqo9ZggzzteejI= +github.com/onflow/flow-go v0.15.3 h1:L6fTJcut93vhPTJb1MkW12W+ja9pmOG1ZTByaoAq28A= +github.com/onflow/flow-go v0.15.3/go.mod h1:Td2+8Is8Jn5PUhEtxjdHjVzKYUNDIiMjHsHsFYEftOw= github.com/onflow/flow-go-sdk v0.15.0 h1:h2FD/d1p/VRIWEcAYcVOT2rm4qKppIn4sVog+/eXKrw= github.com/onflow/flow-go-sdk v0.15.0/go.mod h1:Dkcd1xQta8EPQL5XKE9vi2OTa6CoMsbX0jIQ4ozhUUs= github.com/onflow/flow-go-sdk v0.16.2 h1:QVQoRgGoDZU1g7nJDzK+ticTMGLnjqFviwA6MBMTSOE= github.com/onflow/flow-go-sdk v0.16.2/go.mod h1:qbg42SwWPoVzr6BORyUoi7DFvRsyfeH0sxVDuhRZjfs= +github.com/onflow/flow-go-sdk v0.17.0 h1:NC6GEb1OebiUDkZqWG+5t/QgjjJrham6CXnyRbzHPqg= +github.com/onflow/flow-go-sdk v0.17.0/go.mod h1:AjXHdxguP/PK5P8tWKHH4jR6oLISTgLoXXQrbQsHY+E= github.com/onflow/flow-go/crypto v0.12.0 h1:TMsqn5nsW4vrCIFG/HRE/oy/a5/sffHrDRDYqicwO98= github.com/onflow/flow-go/crypto v0.12.0/go.mod h1:oXuvU0Dr4lHKgye6nHEFbBXIWNv+dBQUzoVW5Go38+o= github.com/onflow/flow/protobuf/go/flow v0.1.9 h1:ugK6/9K4AkMxqPbCvQzbbV24AH50Ozze43nqpukQoOM= github.com/onflow/flow/protobuf/go/flow v0.1.9/go.mod h1:kRugbzZjwQqvevJhrnnCFMJZNmoSJmxlKt6hTGXZojM= +github.com/onflow/flow/protobuf/go/flow v0.2.0 h1:a4Cg0ekoqb76zeOEo1wtSWtlnhGXwcxebp0itFwGtlE= +github.com/onflow/flow/protobuf/go/flow v0.2.0/go.mod h1:kRugbzZjwQqvevJhrnnCFMJZNmoSJmxlKt6hTGXZojM= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -885,6 +908,8 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v0.0.7 h1:FfTH+vuMXOas8jmfb5/M7dzEYx7LpcLb7a0LPe34uOU= +github.com/spf13/cobra v0.0.7/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= @@ -1236,7 +1261,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca h1:pvScuB+UnCGDas2naNKUOXruM08MjwVcEdaweeynIqQ= golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -1249,7 +1273,6 @@ gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJ gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.6.1 h1:/LSrTrgZtpbXyAR6+0e152SROCkJJSh7goYWVmdPFGc= gonum.org/v1/gonum v0.6.1/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0 h1:OE9mWmgKkjJyEmDAAtGMPjXu+YNeGvK9VTSHY6+Qihc= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts= gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= @@ -1350,7 +1373,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 31c57960c..820f0f939 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -21,13 +21,12 @@ package transactions import ( "bytes" "fmt" - "text/tabwriter" - - "github.com/onflow/flow-cli/internal/events" "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" + + "github.com/onflow/flow-cli/internal/events" ) var Cmd = &cobra.Command{ diff --git a/pkg/flowcli/project/account.go b/pkg/flowcli/project/account.go index 768c78e19..5270342b2 100644 --- a/pkg/flowcli/project/account.go +++ b/pkg/flowcli/project/account.go @@ -66,8 +66,6 @@ func accountsFromConfig(conf *config.Config) ([]*Account, error) { } func AccountFromAddressAndKey(address flow.Address, privateKey crypto.PrivateKey) *Account { - key := NewHexAccountKeyFromPrivateKey(0, crypto.SHA3_256, privateKey) - return &Account{ name: "", address: address, From 4591834d9500269af0f5c45ba9aada19aa2ac91d Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Sat, 24 Apr 2021 17:38:07 +0200 Subject: [PATCH 110/171] add authorizer fix --- go.mod | 1 + pkg/flowcli/project/transaction.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index f53e9558a..2467df8b3 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/psiemens/sconfig v0.0.0-20190623041652-6e01eb1354fc github.com/spf13/afero v1.1.2 github.com/spf13/cobra v0.0.7 + github.com/spf13/pflag v1.0.3 // indirect github.com/stretchr/testify v1.7.0 github.com/thoas/go-funk v0.7.0 gonum.org/v1/gonum v0.6.1 diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index 17b1c572e..b9041517b 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -125,7 +125,8 @@ func addAccountContractWithArgs( tx := flow.NewTransaction(). AddRawArgument(jsoncdc.MustEncode(cadenceName)). - AddRawArgument(jsoncdc.MustEncode(cadenceCode)) + AddRawArgument(jsoncdc.MustEncode(cadenceCode)). + AddAuthorizer(signer.Address()) txArgs, addArgs := "", "" for _, arg := range args { From 7d6977300a6c1aed3ea0782ee82f5dff241d5bd3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Sat, 24 Apr 2021 20:33:13 +0200 Subject: [PATCH 111/171] extended integration tests with new functionality --- tests/Bar.cdc | 7 ++++ tests/HelloV2.cdc | 9 +++++ tests/e2e_test.go | 74 ++++++++++++++++++++++++++++-------- tests/flow.json | 26 ++++++++----- tests/scriptImports.cdc | 5 +++ tests/transactionImports.cdc | 13 +++++++ 6 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 tests/Bar.cdc create mode 100644 tests/HelloV2.cdc create mode 100644 tests/scriptImports.cdc create mode 100644 tests/transactionImports.cdc diff --git a/tests/Bar.cdc b/tests/Bar.cdc new file mode 100644 index 000000000..ab9158d4e --- /dev/null +++ b/tests/Bar.cdc @@ -0,0 +1,7 @@ +import Foo from "./Foo.cdc" + +pub contract Bar { + init(a: String, b: UInt32) { + log(a.concat(b.toString())) + } +} diff --git a/tests/HelloV2.cdc b/tests/HelloV2.cdc new file mode 100644 index 000000000..1681ec0fc --- /dev/null +++ b/tests/HelloV2.cdc @@ -0,0 +1,9 @@ +pub contract Hello { + pub let greeting: String + init() { + self.greeting = "Hello, World V2!" + } + pub fun hello(): String { + return self.greeting + } +} diff --git a/tests/e2e_test.go b/tests/e2e_test.go index ee6d19408..7f6c7e3a3 100644 --- a/tests/e2e_test.go +++ b/tests/e2e_test.go @@ -36,6 +36,7 @@ import ( const ( serviceAddress = "f8d6e0586b0a20c7" contractPath = "./Hello.cdc" + contractPathV2 = "./HelloV2.cdc" emulatorAccount = "emulator-account" host = "127.0.0.1:3569" conf = "./flow.json" @@ -50,6 +51,7 @@ func TestAccount(t *testing.T) { } helloContract, _ := io.ReadFile(contractPath) + helloContractV2, _ := io.ReadFile(contractPathV2) gw, err := gateway.NewGrpcGateway(host) assert.NoError(t, err) @@ -66,7 +68,7 @@ func TestAccount(t *testing.T) { assert.Equal(t, account.Address.String(), serviceAddress) }) - t.Run("Creates an Account", func(t *testing.T) { + t.Run("Creates an Account With Single Key", func(t *testing.T) { keys := []string{"0x640a5a359bf3536d15192f18d872d57c98a96cb871b92b70cecb0739c2d5c37b4be12548d3526933c2cda9b0b9c69412f45ffb6b85b6840d8569d969fe84e5b7"} account, err := accounts.Create( emulatorAccount, @@ -79,27 +81,39 @@ func TestAccount(t *testing.T) { assert.NoError(t, err) assert.Equal(t, account.Keys[0].PublicKey.String(), keys[0]) - assert.Equal(t, string(account.Code), "") }) - t.Run("Account Add Contract", func(t *testing.T) { - acc, err := accounts.AddContract( + t.Run("Creates an Account With Three Keys", func(t *testing.T) { + keys := []string{ + "0x7a2b681b34aa47c85a9a231a62db395ccd448abcba24dcea3243971b42bc47bc90eac75064a7fda218768efe17bfcc0909ad661f4748650ce812e9aeff8a60a2", + "0x49ce6f0a0f45514927849202db9f811e825c4a93324e0ce2a005e7180766a9f55e0ce503c954717f7f8108f90111a64aa4c6b83b261670da81ab5d26145be98e", + "0x9e7caa551ba5ba623b763f69ad76e62e0df071174a4a74077b3def6077652ec89a3b2c4855e0841b903eedc23aeb5f9b6d85f7aab6e41356884533cd44f4402d", + } + + weights := []int{500, 500, 500} + + account, err := accounts.Create( emulatorAccount, - "Hello", - contractPath, - false, + keys, + weights, + "ECDSA_P256", + "SHA3_256", + []string{}, ) assert.NoError(t, err) - assert.Equal(t, string(acc.Contracts["Hello"]), string(helloContract)) + assert.Equal(t, account.Keys[0].PublicKey.String(), keys[0]) + assert.Equal(t, account.Keys[1].PublicKey.String(), keys[1]) + assert.Equal(t, account.Keys[2].PublicKey.String(), keys[2]) + assert.Len(t, account.Keys, 3) }) - t.Run("Account Update Contract", func(t *testing.T) { + t.Run("Account Add Contract", func(t *testing.T) { acc, err := accounts.AddContract( emulatorAccount, "Hello", contractPath, - true, + false, ) assert.NoError(t, err) @@ -110,12 +124,12 @@ func TestAccount(t *testing.T) { acc, err := accounts.AddContract( emulatorAccount, "Hello", - contractPath, + contractPathV2, true, ) assert.NoError(t, err) - assert.Equal(t, string(acc.Contracts["Hello"]), string(helloContract)) + assert.Equal(t, string(acc.Contracts["Hello"]), string(helloContractV2)) }) t.Run("Account Remove Contract", func(t *testing.T) { @@ -183,14 +197,14 @@ func TestProject(t *testing.T) { projects := services.NewProject(gw, project, logger) - t.Run("Deploy project", func(t *testing.T) { + t.Run("Deploy Project with Args", func(t *testing.T) { contracts, err := projects.Deploy("emulator", true) assert.NoError(t, err) assert.Equal(t, contracts[0].Name(), "NonFungibleToken") assert.Equal(t, contracts[1].Name(), "Foo") assert.Equal(t, contracts[1].Dependencies()["./NonFungibleToken.cdc"].Target(), contracts[0].Target()) - assert.Equal(t, len(contracts), 2) + assert.Equal(t, len(contracts), 3) }) } @@ -208,7 +222,12 @@ func TestScripts(t *testing.T) { scripts := services.NewScripts(gateway, project, logger) t.Run("Test Script", func(t *testing.T) { - val, err := scripts.Execute("./script.cdc", []string{"String:Mr G"}, "", "") + val, err := scripts.Execute( + "./script.cdc", + []string{"String:Mr G"}, + "", + "", + ) assert.NoError(t, err) assert.Equal(t, val.String(), `"Hello Mr G"`) @@ -225,6 +244,18 @@ func TestScripts(t *testing.T) { assert.NoError(t, err) assert.Equal(t, val.String(), `"Hello Mr G"`) }) + + t.Run("Test Script with Imports", func(t *testing.T) { + val, err := scripts.Execute( + "./scriptImports.cdc", + []string{}, + "", + "emulator", + ) + + assert.NoError(t, err) + assert.Equal(t, val.String(), `"Hello"`) + }) } func TestTransactions(t *testing.T) { @@ -255,6 +286,19 @@ func TestTransactions(t *testing.T) { assert.Equal(t, tr.Status.String(), "SEALED") }) + t.Run("Test Transactions with Imports", func(t *testing.T) { + tx, tr, err := transactions.Send( + "./transactionImports.cdc", + emulatorAccount, []string{}, "", + "emulator", + ) + + assert.NoError(t, err) + assert.NoError(t, tr.Error) + assert.Equal(t, tx.Payer.String(), serviceAddress) + assert.Equal(t, tr.Status.String(), "SEALED") + }) + t.Run("Test Failed Transactions", func(t *testing.T) { tx, tr, err := transactions.Send( "./transactionErr.cdc", diff --git a/tests/flow.json b/tests/flow.json index 8389216b8..95c9e358c 100644 --- a/tests/flow.json +++ b/tests/flow.json @@ -6,31 +6,39 @@ } }, "contracts": { - "NonFungibleToken": "./NonFungibleToken.cdc", "Foo": "./Foo.cdc", + "Bar": "./Bar.cdc", + "NonFungibleToken": "./NonFungibleToken.cdc", "FungibleToken": { "source": "./FungibleToken.cdc", "aliases": { - "emulator": "ee82856bf20e2aa6" + "emulator": "0xee82856bf20e2aa6" } } }, "networks": { - "emulator": { - "host": "127.0.0.1:3569", - "chain": "flow-emulator" - } + "emulator": "127.0.0.1:3569", + "mainnet": "access.mainnet.nodes.onflow.org:9000", + "testnet": "access.devnet.nodes.onflow.org:9000" }, "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - "chain": "flow-emulator" + "key": "12868d0829a38b31301394cba9cee25bf18833f1d436de2e39af86afa1c01afc" } }, "deployments": { "emulator": { - "emulator-account": ["NonFungibleToken", "Foo"] + "emulator-account": [ + "Foo", + "NonFungibleToken", { + "name": "Bar", + "args": [ + { "name": "a", "type": "String", "value": "Hello World" }, + { "name": "b", "type": "UInt32", "value": "10" } + ] + } + ] } } } \ No newline at end of file diff --git a/tests/scriptImports.cdc b/tests/scriptImports.cdc new file mode 100644 index 000000000..cdb838d28 --- /dev/null +++ b/tests/scriptImports.cdc @@ -0,0 +1,5 @@ +import Bar from "./Bar.cdc" + +pub fun main(): String { + return "Hello" +} \ No newline at end of file diff --git a/tests/transactionImports.cdc b/tests/transactionImports.cdc new file mode 100644 index 000000000..cacf787d4 --- /dev/null +++ b/tests/transactionImports.cdc @@ -0,0 +1,13 @@ +import Bar from "./Bar.cdc" + +transaction() { + let guest: Address + + prepare(authorizer: AuthAccount) { + self.guest = authorizer.address + } + + execute { + log(self.guest.toString()) + } +} \ No newline at end of file From 72a379d061eae1665545304001f386d8565561c6 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Sat, 24 Apr 2021 21:32:35 +0200 Subject: [PATCH 112/171] refactor network --- internal/command/command.go | 2 -- internal/status/status.go | 17 +++++------------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index 6db2166f3..29c4ae78a 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -61,8 +61,6 @@ type GlobalFlags struct { ConfigPath []string } -const NetworkEmulator = "emulator" - const ( formatText = "text" formatInline = "inline" diff --git a/internal/status/status.go b/internal/status/status.go index eea7d625c..2a8551976 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -44,29 +44,22 @@ var Command = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - // Get network name from global flag - network := globalFlags.Network - if network == "" { - network = command.NetworkEmulator - } - - accessNode, err := services.Status.Ping(network) + accessNode, err := services.Status.Ping(globalFlags.Network) return &Result{ - network: network, + network: globalFlags.Network, accessNode: accessNode, - err: err, + err: err, }, nil }, } type Result struct { - network string + network string accessNode string - err error + err error } - const ( OnlineIcon = "🟢" OnlineStatus = "ONLINE" From 54081fd8d7ec3e9bb8599a22e2764f98caa0387e Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Sat, 24 Apr 2021 22:41:18 +0200 Subject: [PATCH 113/171] comment fix --- pkg/flowcli/services/scripts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/services/scripts.go b/pkg/flowcli/services/scripts.go index 9aa72d5c3..7c2a71bd9 100644 --- a/pkg/flowcli/services/scripts.go +++ b/pkg/flowcli/services/scripts.go @@ -61,7 +61,7 @@ func (s *Scripts) Execute(scriptPath string, args []string, argsJSON string, net return s.execute(script, args, argsJSON, scriptPath, network) } -// Execute executes a Cadence script from a source code string. +// ExecuteWithCode executes a Cadence script from a source code string. func (s *Scripts) ExecuteWithCode(code []byte, args []string, argsJSON string) (cadence.Value, error) { return s.execute(code, args, argsJSON, "", "") } From f5a077eabae03813a685b9d6eca571e10c1306f3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Sat, 24 Apr 2021 22:48:48 +0200 Subject: [PATCH 114/171] merge fix --- internal/completion/completion.go | 82 ------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 internal/completion/completion.go diff --git a/internal/completion/completion.go b/internal/completion/completion.go deleted file mode 100644 index 14aed1ff8..000000000 --- a/internal/completion/completion.go +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Flow CLI - * - * Copyright 2019-2021 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 completion - -import ( - "os" - - "github.com/spf13/cobra" -) - -var Cmd = &cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", - Short: "Generate completion script", - Long: `To load completions: - -Bash: - - $ source <(yourprogram completion bash) - - # To load completions for each session, execute once: - # Linux: - $ yourprogram completion bash > /etc/bash_completion.d/yourprogram - # macOS: - $ yourprogram completion bash > /usr/local/etc/bash_completion.d/yourprogram - -Zsh: - - # If shell completion is not already enabled in your environment, - # you will need to enable it. You can execute the following once: - - $ echo "autoload -U compinit; compinit" >> ~/.zshrc - - # To load completions for each session, execute once: - $ yourprogram completion zsh > "${fpath[1]}/_yourprogram" - - # You will need to start a new shell for this setup to take effect. - -fish: - - $ yourprogram completion fish | source - - # To load completions for each session, execute once: - $ yourprogram completion fish > ~/.config/fish/completions/yourprogram.fish - -PowerShell: - - PS> yourprogram completion powershell | Out-String | Invoke-Expression - - # To load completions for every new session, run: - PS> yourprogram completion powershell > yourprogram.ps1 - # and source this file from your PowerShell profile. -`, - DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, - Args: cobra.ExactValidArgs(1), - Run: func(cmd *cobra.Command, args []string) { - switch args[0] { - case "bash": - cmd.Root().GenBashCompletion(os.Stdout) - case "zsh": - cmd.Root().GenZshCompletion(os.Stdout) - case "powershell": - cmd.Root().GenPowerShellCompletion(os.Stdout) - } - }, -} From b223372b6dca337f28a7fad62c5ec4fd4992cee7 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 09:05:44 -0400 Subject: [PATCH 115/171] remove completion module --- cmd/flow/main.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 3b4b7ffe4..83417e355 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -20,7 +20,6 @@ package main import ( - "github.com/onflow/flow-cli/internal/completion" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/accounts" @@ -64,8 +63,6 @@ func main() { cmd.AddCommand(project.Cmd) cmd.AddCommand(config.Cmd) - cmd.AddCommand(completion.Cmd) - command.InitFlags(cmd) if err := cmd.Execute(); err != nil { From 100a5b8337fa670fc7fe443bfeefbdf20e92dfa3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 10:03:55 -0400 Subject: [PATCH 116/171] renamed struct var --- internal/events/events.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/events/events.go b/internal/events/events.go index c561959be..22b75fb64 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -47,9 +47,9 @@ type EventResult struct { } // JSON convert result to JSON -func (k *EventResult) JSON() interface{} { +func (e *EventResult) JSON() interface{} { result := make(map[string]map[uint64]map[string]interface{}) - for _, blockEvent := range k.BlockEvents { + for _, blockEvent := range e.BlockEvents { if len(blockEvent.Events) > 0 { for _, event := range blockEvent.Events { result["blockId"][blockEvent.Height]["index"] = event.EventIndex @@ -64,11 +64,11 @@ func (k *EventResult) JSON() interface{} { } // String convert result to string -func (k *EventResult) String() string { +func (e *EventResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - for _, blockEvent := range k.BlockEvents { + for _, blockEvent := range e.BlockEvents { if len(blockEvent.Events) > 0 { fmt.Fprintf(writer, "Events Block #%v:", blockEvent.Height) eventsString(writer, blockEvent.Events) @@ -77,16 +77,16 @@ func (k *EventResult) String() string { } // if we have events passed directly and not in relation to block - eventsString(writer, k.Events) + eventsString(writer, e.Events) writer.Flush() return b.String() } // Oneliner show result as one liner grep friendly -func (k *EventResult) Oneliner() string { +func (e *EventResult) Oneliner() string { result := "" - for _, blockEvent := range k.BlockEvents { + for _, blockEvent := range e.BlockEvents { if len(blockEvent.Events) > 0 { result += fmt.Sprintf("Events Block #%v: [", blockEvent.Height) for _, event := range blockEvent.Events { From ec42f6c398a72d44262b72dd4d2a415e8a9f1290 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 11:47:09 -0400 Subject: [PATCH 117/171] move add commands in seperate files --- internal/config/account.go | 20 ------- internal/config/add-account.go | 92 +++++++++++++++++++++++++++++++ internal/config/add-contract.go | 1 + internal/config/add-deployment.go | 1 + internal/config/add-network.go | 1 + internal/config/add.go | 2 +- 6 files changed, 96 insertions(+), 21 deletions(-) delete mode 100644 internal/config/account.go create mode 100644 internal/config/add-account.go create mode 100644 internal/config/add-contract.go create mode 100644 internal/config/add-deployment.go create mode 100644 internal/config/add-network.go diff --git a/internal/config/account.go b/internal/config/account.go deleted file mode 100644 index 1f94a0e17..000000000 --- a/internal/config/account.go +++ /dev/null @@ -1,20 +0,0 @@ -package config - -import ( - "github.com/onflow/flow-cli/internal/command" - "github.com/spf13/cobra" -) - -type flagsAccount struct{} - -var accountFlags = flagsAccount{} - -var AccountCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "add account", - Short: "Add resource to configuration", - Example: "flow config add account", - ValidArgs: []string{"account", "contract", "deployment", "network"}, - Args: cobra.ExactArgs(1), - }, -} diff --git a/internal/config/add-account.go b/internal/config/add-account.go new file mode 100644 index 000000000..a961ada42 --- /dev/null +++ b/internal/config/add-account.go @@ -0,0 +1,92 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsAddAccount struct { + Name string `flag:"name" info:"Name for the account"` + Address string `flag:"address" info:"Account address"` + KeyIndex string `default:"0" flag:"key-index" info:"Account key index"` + SigAlgo string `default:"ECDSA_P256" flag:"sig-algo" info:"Account key signature algorithm"` + HashAlgo string `default:"SHA3_256" flag:"hash-algo" info:"Account hash used for the digest"` + Key string `flag:"key" info:"Account private key"` +} + +var addAccountFlags = flagsAddAccount{} + +var AddAccountCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "account", + Short: "Add account to configuration", + Example: "flow config add account", + Args: cobra.NoArgs, + }, + Flags: &addAccountFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + accountData, flagsProvided, err := flagsToAccountData(addAccountFlags) + if err != nil { + return nil, err + } + + if !flagsProvided { + accountData = output.NewAccountPrompt() + } + + account, err := config.StringToAccount( + accountData["name"], + accountData["address"], + accountData["keyIndex"], + accountData["sigAlgo"], + accountData["hashAlgo"], + accountData["key"], + ) + if err != nil { + return nil, err + } + + err = services.Config.AddAccount(*account) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "account added", + }, nil + + }, +} + +func flagsToAccountData(flags flagsAddAccount) (map[string]string, bool, error) { + if flags.Name == "" && flags.Address == "" && flags.Key == "" { + return nil, false, nil + } + + if flags.Name == "" { + return nil, true, fmt.Errorf("name must be provided") + } else if flags.Address == "" { + return nil, true, fmt.Errorf("address must be provided") + } else if flags.Key == "" { + return nil, true, fmt.Errorf("key must be provided") + } + + return map[string]string{ + "name": flags.Name, + "address": flags.Address, + "keyIndex": flags.KeyIndex, + "sigAlgo": flags.SigAlgo, + "hashAlg": flags.HashAlgo, + "key": flags.Key, + }, true, nil +} diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go new file mode 100644 index 000000000..d912156be --- /dev/null +++ b/internal/config/add-contract.go @@ -0,0 +1 @@ +package config diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go new file mode 100644 index 000000000..d912156be --- /dev/null +++ b/internal/config/add-deployment.go @@ -0,0 +1 @@ +package config diff --git a/internal/config/add-network.go b/internal/config/add-network.go new file mode 100644 index 000000000..d912156be --- /dev/null +++ b/internal/config/add-network.go @@ -0,0 +1 @@ +package config diff --git a/internal/config/add.go b/internal/config/add.go index d0e08b69e..abac42658 100644 --- a/internal/config/add.go +++ b/internal/config/add.go @@ -17,7 +17,7 @@ var addFlags = flagsAdd{} var AddCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "add account", + Use: "add ", Short: "Add resource to configuration", Example: "flow config add account", ValidArgs: []string{"account", "contract", "deployment", "network"}, From 1a04ea1828abccb0729ec3ca9c164ff91268d332 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 12:02:32 -0400 Subject: [PATCH 118/171] added headers --- internal/config/add-account.go | 23 +++++++++++++++++++++++ internal/config/add-deployment.go | 18 ++++++++++++++++++ internal/config/add.go | 18 ++++++++++++++++++ internal/config/config.go | 18 ++++++++++++++++++ internal/config/remove.go | 18 ++++++++++++++++++ 5 files changed, 95 insertions(+) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index a961ada42..a51f78d66 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( @@ -81,6 +99,11 @@ func flagsToAccountData(flags flagsAddAccount) (map[string]string, bool, error) return nil, true, fmt.Errorf("key must be provided") } + _, err := config.StringToAddress(flags.Address) + if err != nil { + return nil, true, err + } + return map[string]string{ "name": flags.Name, "address": flags.Address, diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index d912156be..e918966b3 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -1 +1,19 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config diff --git a/internal/config/add.go b/internal/config/add.go index abac42658..e51bdb10c 100644 --- a/internal/config/add.go +++ b/internal/config/add.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( diff --git a/internal/config/config.go b/internal/config/config.go index e22268ef5..a69b5d7f2 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( diff --git a/internal/config/remove.go b/internal/config/remove.go index bab239570..0f6bbb12b 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( From e2344feb410ebd162d4d7ace3c7de46f2e98b65f Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 12:02:42 -0400 Subject: [PATCH 119/171] added contract cmd --- internal/config/add-contract.go | 114 ++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index d912156be..e5d3103c9 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -1 +1,115 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsAddContract struct { + Name string `flag:"name" info:"Name of the contract"` + Filename string `flag:"filename" info:"Filename of the contract source"` + EmulatorAlias string `flag:"emulator-alias" info:"Address for the emulator alias"` + TestnetAlias string `flag:"testnet-alias" info:"Address for the testnet alias"` +} + +var addContractFlags = flagsAddContract{} + +var AddContractCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "contract", + Short: "Add contract to configuration", + Example: "flow config add contract", + Args: cobra.NoArgs, + }, + Flags: &addContractFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + contractData, flagsProvided, err := flagsToContractData(addContractFlags) + if err != nil { + return nil, err + } + + if !flagsProvided { + contractData = output.NewContractPrompt() + } + + contractData = output.NewContractPrompt() + contracts := config.StringToContracts( + contractData["name"], + contractData["source"], + contractData["emulator"], + contractData["testnet"], + ) + + err = services.Config.AddContracts(contracts) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "contract added", + }, nil + }, +} + +func flagsToContractData(flags flagsAddContract) (map[string]string, bool, error) { + if flags.Name == "" && flags.Filename == "" { + return nil, false, nil + } + + if flags.Name == "" { + return nil, true, fmt.Errorf("name must be provided") + } else if flags.Filename == "" { + return nil, true, fmt.Errorf("contract file name must be provided") + } else if !config.Exists(flags.Filename) { + return nil, true, fmt.Errorf("contract file doesn't exist: %s", flags.Filename) + } + + if flags.EmulatorAlias != "" { + _, err := config.StringToAddress(flags.EmulatorAlias) + if err != nil { + return nil, true, err + } + } + + if flags.TestnetAlias != "" { + _, err := config.StringToAddress(flags.TestnetAlias) + if err != nil { + return nil, true, err + } + } + + return map[string]string{ + "name": flags.Name, + "source": flags.Filename, + "emulator": flags.EmulatorAlias, + "testnet": flags.TestnetAlias, + }, true, nil +} From df6d08f167f6d5285232a5c99e8f73ef064d86fe Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 12:08:31 -0400 Subject: [PATCH 120/171] added network cmd --- internal/config/add-network.go | 95 ++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/internal/config/add-network.go b/internal/config/add-network.go index d912156be..03fe5dd89 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -1 +1,96 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config + +import ( + "fmt" + "net/url" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsAddNetwork struct { + Name string `flag:"name" info:"Network name"` + Host string `flag:"host" info:"Flow Access API host address"` +} + +var addNetworkFlags = flagsAddNetwork{} + +var AddNetworkCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "network", + Short: "Add network to configuration", + Example: "flow config add network", + Args: cobra.NoArgs, + }, + Flags: &addNetworkFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + networkData, flagsProvided, err := flagsToNetworkData(addNetworkFlags) + if err != nil { + return nil, err + } + + if !flagsProvided { + networkData = output.NewNetworkPrompt() + } + + networkData = output.NewNetworkPrompt() + network := config.StringToNetwork(networkData["name"], networkData["host"]) + + err = services.Config.AddNetwork(network) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "network added", + }, nil + }, +} + +func flagsToNetworkData(flags flagsAddNetwork) (map[string]string, bool, error) { + if flags.Name == "" && flags.Host == "" { + return nil, false, nil + } + + if flags.Name == "" { + return nil, true, fmt.Errorf("name must be provided") + } else if flags.Host == "" { + return nil, true, fmt.Errorf("contract file name must be provided") + } + + _, err := url.ParseRequestURI(flags.Host) + if err != nil { + return nil, true, err + } + + return map[string]string{ + "name": flags.Name, + "host": flags.Host, + }, true, nil +} From e3a652126f0f58a62a503112df4fb1d586cfc7b7 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 12:26:08 -0400 Subject: [PATCH 121/171] added deployment cmd --- internal/config/add-deployment.go | 88 +++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index e918966b3..40c59c546 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -17,3 +17,91 @@ */ package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsAddDeployment struct { + Network string `flag:"network" info:"Network name used for deployment"` + Account string `flag:"account" info:"Account name used for deployment"` + Contracts []string `flag:"contract" info:"Name of the contract to be deployed"` +} + +var addDeploymentFlags = flagsAddDeployment{} + +var AddDeploymentCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "deployment", + Short: "Add deployment to configuration", + Example: "flow config add deployment", + Args: cobra.NoArgs, + }, + Flags: &addDeploymentFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + conf := p.Config() + + deployData, flagsProvided, err := flagsToDeploymentData(addDeploymentFlags) + if err != nil { + return nil, err + } + + if !flagsProvided { + deployData = output.NewDeploymentPrompt(conf.Networks, conf.Accounts, conf.Contracts) + } + + deployment := config.StringToDeployment( + deployData["network"].(string), + deployData["account"].(string), + deployData["contracts"].([]string), + ) + err = services.Config.AddDeployment(deployment) + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "deploy added", + }, nil + }, +} + +func init() { + AddDeploymentCommand.AddToParent(AddCmd) +} + +func flagsToDeploymentData(flags flagsAddDeployment) (map[string]interface{}, bool, error) { + if flags.Network == "" && flags.Account == "" && len(flags.Contracts) == 0 { + return nil, false, nil + } + + if flags.Network == "" { + return nil, true, fmt.Errorf("network name must be provided") + } else if flags.Account == "" { + return nil, true, fmt.Errorf("account name must be provided") + } else if len(flags.Contracts) == 0 { + return nil, true, fmt.Errorf("at least one contract name must be provided") + } + + return map[string]interface{}{ + "network": flags.Network, + "account": flags.Account, + "contracts": flags.Contracts, + }, true, nil +} From 1f652a78a876b5b4a009c12a3a81867343c11120 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 12:26:15 -0400 Subject: [PATCH 122/171] refactor add commands --- internal/config/add-account.go | 4 ++ internal/config/add-contract.go | 4 ++ internal/config/add-network.go | 4 ++ internal/config/add.go | 115 ++------------------------------ internal/config/config.go | 2 +- 5 files changed, 20 insertions(+), 109 deletions(-) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index a51f78d66..c391b9fe0 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -86,6 +86,10 @@ var AddAccountCommand = &command.Command{ }, } +func init() { + AddAccountCommand.AddToParent(AddCmd) +} + func flagsToAccountData(flags flagsAddAccount) (map[string]string, bool, error) { if flags.Name == "" && flags.Address == "" && flags.Key == "" { return nil, false, nil diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index e5d3103c9..d0bae6f45 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -79,6 +79,10 @@ var AddContractCommand = &command.Command{ }, } +func init() { + AddContractCommand.AddToParent(AddCmd) +} + func flagsToContractData(flags flagsAddContract) (map[string]string, bool, error) { if flags.Name == "" && flags.Filename == "" { return nil, false, nil diff --git a/internal/config/add-network.go b/internal/config/add-network.go index 03fe5dd89..ec4b897bf 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -73,6 +73,10 @@ var AddNetworkCommand = &command.Command{ }, } +func init() { + AddNetworkCommand.AddToParent(AddCmd) +} + func flagsToNetworkData(flags flagsAddNetwork) (map[string]string, bool, error) { if flags.Name == "" && flags.Host == "" { return nil, false, nil diff --git a/internal/config/add.go b/internal/config/add.go index e51bdb10c..a84e16937 100644 --- a/internal/config/add.go +++ b/internal/config/add.go @@ -19,115 +19,14 @@ package config import ( - "fmt" - - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/pkg/flowcli/config" - "github.com/onflow/flow-cli/pkg/flowcli/output" - "github.com/onflow/flow-cli/pkg/flowcli/project" - "github.com/onflow/flow-cli/pkg/flowcli/services" "github.com/spf13/cobra" ) -type flagsAdd struct{} - -var addFlags = flagsAdd{} - -var AddCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "add ", - Short: "Add resource to configuration", - Example: "flow config add account", - ValidArgs: []string{"account", "contract", "deployment", "network"}, - Args: cobra.ExactArgs(1), - }, - Flags: &addFlags, - Run: func( - cmd *cobra.Command, - args []string, - globalFlags command.GlobalFlags, - services *services.Services, - ) (command.Result, error) { - resource := args[0] - - p, err := project.Load(globalFlags.ConfigPath) - if err != nil { - return nil, fmt.Errorf("configuration does not exists") - } - conf := p.Config() - - switch resource { - case "account": - accountData := output.NewAccountPrompt() - account, err := config.StringToAccount( - accountData["name"], - accountData["address"], - accountData["keyIndex"], - accountData["sigAlgo"], - accountData["hashAlgo"], - accountData["key"], - ) - if err != nil { - return nil, err - } - - err = services.Config.AddAccount(*account) - if err != nil { - return nil, err - } - - return &ConfigResult{ - result: "account added", - }, nil - - case "contract": - contractData := output.NewContractPrompt() - contracts := config.StringToContracts( - contractData["name"], - contractData["source"], - contractData["emulator"], - contractData["testnet"], - ) - - err := services.Config.AddContracts(contracts) - if err != nil { - return nil, err - } - - return &ConfigResult{ - result: "contract added", - }, nil - - case "deployment": - deployData := output.NewDeploymentPrompt(conf.Networks, conf.Accounts, conf.Contracts) - deployment := config.StringToDeployment( - deployData["network"].(string), - deployData["account"].(string), - deployData["contracts"].([]string), - ) - err := services.Config.AddDeployment(deployment) - if err != nil { - return nil, err - } - - return &ConfigResult{ - result: "deploy added", - }, nil - - case "network": - networkData := output.NewNetworkPrompt() - network := config.StringToNetwork(networkData["name"], networkData["host"]) - - err := services.Config.AddNetwork(network) - if err != nil { - return nil, err - } - - return &ConfigResult{ - result: "network added", - }, nil - } - - return nil, nil - }, +var AddCmd = &cobra.Command{ + Use: "add ", + Short: "Add resource to configuration", + Example: "flow config add account", + ValidArgs: []string{"account", "contract", "deployment", "network"}, + Args: cobra.ExactArgs(1), + TraverseChildren: true, } diff --git a/internal/config/config.go b/internal/config/config.go index a69b5d7f2..c16f8e94f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -30,7 +30,7 @@ var Cmd = &cobra.Command{ func init() { //InitCommand.AddToParent(Cmd) - AddCommand.AddToParent(Cmd) + Cmd.AddCommand(AddCmd) RemoveCommand.AddToParent(Cmd) } From d029653a630c1494157abc5ec15c99f25c5848ff Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Mon, 26 Apr 2021 12:29:11 -0400 Subject: [PATCH 123/171] remove support flags --- internal/config/remove.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/internal/config/remove.go b/internal/config/remove.go index 0f6bbb12b..71381f54c 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -28,7 +28,9 @@ import ( "github.com/spf13/cobra" ) -type flagsRemove struct{} +type flagsRemove struct { + Name string `flag:"name" info:"Resource name"` +} var removeFlags = flagsRemove{} @@ -57,7 +59,11 @@ var RemoveCommand = &command.Command{ switch resource { case "account": - name := output.RemoveAccountPrompt(conf.Accounts) + name := removeFlags.Name + if name == "" { + name = output.RemoveAccountPrompt(conf.Accounts) + } + err := services.Config.RemoveAccount(name) if err != nil { return nil, err @@ -79,7 +85,11 @@ var RemoveCommand = &command.Command{ }, nil case "contract": - name := output.RemoveContractPrompt(conf.Contracts) + name := removeFlags.Name + if name == "" { + name = output.RemoveContractPrompt(conf.Contracts) + } + err := services.Config.RemoveContract(name) if err != nil { return nil, err @@ -90,7 +100,11 @@ var RemoveCommand = &command.Command{ }, nil case "network": - name := output.RemoveNetworkPrompt(conf.Networks) + name := removeFlags.Name + if name == "" { + name = output.RemoveNetworkPrompt(conf.Networks) + } + err := services.Config.RemoveNetwork(name) if err != nil { return nil, err From e49a197035ae76183693465fe80ac2bac781807c Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 07:03:13 -0400 Subject: [PATCH 124/171] delete service layer --- pkg/flowcli/services/config.go | 127 --------------------------------- 1 file changed, 127 deletions(-) delete mode 100644 pkg/flowcli/services/config.go diff --git a/pkg/flowcli/services/config.go b/pkg/flowcli/services/config.go deleted file mode 100644 index 1234d013e..000000000 --- a/pkg/flowcli/services/config.go +++ /dev/null @@ -1,127 +0,0 @@ -package services - -import ( - "fmt" - - "github.com/onflow/flow-cli/pkg/flowcli/config" - "github.com/onflow/flow-cli/pkg/flowcli/gateway" - "github.com/onflow/flow-cli/pkg/flowcli/output" - "github.com/onflow/flow-cli/pkg/flowcli/project" -) - -// Accounts is a service that handles all account-related interactions. -type Config struct { - gateway gateway.Gateway - project *project.Project - logger output.Logger -} - -// NewAccounts returns a new accounts service. -func NewConfig( - gateway gateway.Gateway, - project *project.Project, - logger output.Logger, -) *Config { - return &Config{ - gateway: gateway, - project: project, - logger: logger, - } -} - -// TODO maybe this service layer is not needed - -func (c *Config) AddAccount(account config.Account) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - c.project.Config().Accounts.AddOrUpdate(account.Name, account) - - return c.project.SaveDefault() -} - -// todo not removed as it is in config -func (c *Config) RemoveAccount(name string) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - err := c.project.Config().Accounts.Remove(name) - if err != nil { - return err - } - - return c.project.SaveDefault() -} - -func (c *Config) AddContracts(contracts []config.Contract) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - for _, contract := range contracts { - c.project.Config().Contracts.AddOrUpdate(contract.Name, contract) - } - - return c.project.SaveDefault() -} - -func (c *Config) RemoveContract(name string) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - err := c.project.Config().Contracts.Remove(name) - if err != nil { - return err - } - - return c.project.SaveDefault() -} - -func (c *Config) AddNetwork(network config.Network) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - c.project.Config().Networks.AddOrUpdate(network.Name, network) - - return c.project.SaveDefault() -} - -func (c *Config) RemoveNetwork(name string) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - err := c.project.Config().Networks.Remove(name) - if err != nil { - return err - } - - return c.project.SaveDefault() -} - -func (c *Config) AddDeployment(deployment config.Deploy) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - c.project.Config().Deployments.AddOrUpdate(deployment) - - return c.project.SaveDefault() -} - -func (c *Config) RemoveDeployment(account string, network string) error { - if c.project == nil { - return fmt.Errorf("missing configuration, initialize it: flow init") - } - - err := c.project.Config().Deployments.Remove(account, network) - if err != nil { - return err - } - - return c.project.SaveDefault() -} From a9e2b317c78cd3bb2f1cf6d96a6b196b6105096d Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 07:15:17 -0400 Subject: [PATCH 125/171] refactored out service layer --- internal/config/add-account.go | 10 +++++++++- internal/config/add-contract.go | 13 ++++++++++++- internal/config/add-deployment.go | 5 ++++- internal/config/add-network.go | 11 ++++++++++- internal/config/config.go | 2 +- internal/config/remove.go | 26 ++++++++++++++------------ 6 files changed, 50 insertions(+), 17 deletions(-) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index c391b9fe0..f54948c77 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -21,6 +21,8 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" @@ -53,6 +55,11 @@ var AddAccountCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + accountData, flagsProvided, err := flagsToAccountData(addAccountFlags) if err != nil { return nil, err @@ -74,7 +81,8 @@ var AddAccountCommand = &command.Command{ return nil, err } - err = services.Config.AddAccount(*account) + p.Config().Accounts.AddOrUpdate(account.Name, *account) + err = p.SaveDefault() if err != nil { return nil, err } diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index d0bae6f45..93e62d481 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -21,6 +21,8 @@ package config import ( "fmt" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" @@ -51,6 +53,11 @@ var AddContractCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + contractData, flagsProvided, err := flagsToContractData(addContractFlags) if err != nil { return nil, err @@ -68,7 +75,11 @@ var AddContractCommand = &command.Command{ contractData["testnet"], ) - err = services.Config.AddContracts(contracts) + for _, contract := range contracts { + p.Config().Contracts.AddOrUpdate(contract.Name, contract) + } + + err = p.SaveDefault() if err != nil { return nil, err } diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index 40c59c546..39e530807 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -71,7 +71,10 @@ var AddDeploymentCommand = &command.Command{ deployData["account"].(string), deployData["contracts"].([]string), ) - err = services.Config.AddDeployment(deployment) + + conf.Deployments.AddOrUpdate(deployment) + + err = p.SaveDefault() if err != nil { return nil, err } diff --git a/internal/config/add-network.go b/internal/config/add-network.go index ec4b897bf..7ddce8695 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -22,6 +22,8 @@ import ( "fmt" "net/url" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" @@ -50,6 +52,11 @@ var AddNetworkCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + networkData, flagsProvided, err := flagsToNetworkData(addNetworkFlags) if err != nil { return nil, err @@ -62,7 +69,9 @@ var AddNetworkCommand = &command.Command{ networkData = output.NewNetworkPrompt() network := config.StringToNetwork(networkData["name"], networkData["host"]) - err = services.Config.AddNetwork(network) + p.Config().Networks.AddOrUpdate(network.Name, network) + + err = p.SaveDefault() if err != nil { return nil, err } diff --git a/internal/config/config.go b/internal/config/config.go index c16f8e94f..8e90d4985 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -34,7 +34,7 @@ func init() { RemoveCommand.AddToParent(Cmd) } -// configResult result from configuration +// ConfigResult result from configuration type ConfigResult struct { result string } diff --git a/internal/config/remove.go b/internal/config/remove.go index 71381f54c..4ccb88f6b 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -28,19 +28,17 @@ import ( "github.com/spf13/cobra" ) -type flagsRemove struct { - Name string `flag:"name" info:"Resource name"` -} +type flagsRemove struct{} var removeFlags = flagsRemove{} var RemoveCommand = &command.Command{ Cmd: &cobra.Command{ - Use: "remove ", + Use: "remove ", Short: "Remove resource from configuration", Example: "flow config remove account", ValidArgs: []string{"account", "contract", "deployment", "network"}, - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), }, Flags: &removeFlags, Run: func( @@ -50,6 +48,7 @@ var RemoveCommand = &command.Command{ services *services.Services, ) (command.Result, error) { resource := args[0] + name := args[1] p, err := project.Load(globalFlags.ConfigPath) if err != nil { @@ -59,12 +58,11 @@ var RemoveCommand = &command.Command{ switch resource { case "account": - name := removeFlags.Name if name == "" { name = output.RemoveAccountPrompt(conf.Accounts) } - err := services.Config.RemoveAccount(name) + err = conf.Accounts.Remove(name) if err != nil { return nil, err } @@ -75,7 +73,8 @@ var RemoveCommand = &command.Command{ case "deployment": accountName, networkName := output.RemoveDeploymentPrompt(conf.Deployments) - err := services.Config.RemoveDeployment(accountName, networkName) + + err = conf.Deployments.Remove(accountName, networkName) if err != nil { return nil, err } @@ -85,12 +84,11 @@ var RemoveCommand = &command.Command{ }, nil case "contract": - name := removeFlags.Name if name == "" { name = output.RemoveContractPrompt(conf.Contracts) } - err := services.Config.RemoveContract(name) + err = conf.Contracts.Remove(name) if err != nil { return nil, err } @@ -100,12 +98,11 @@ var RemoveCommand = &command.Command{ }, nil case "network": - name := removeFlags.Name if name == "" { name = output.RemoveNetworkPrompt(conf.Networks) } - err := services.Config.RemoveNetwork(name) + err = conf.Networks.Remove(name) if err != nil { return nil, err } @@ -115,6 +112,11 @@ var RemoveCommand = &command.Command{ }, nil } + err = p.SaveDefault() + if err != nil { + return nil, err + } + return nil, nil }, } From d431859b3898d8c2f07fb039f1a25642e55914a6 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 07:17:05 -0400 Subject: [PATCH 126/171] remove from services config --- pkg/flowcli/services/services.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/flowcli/services/services.go b/pkg/flowcli/services/services.go index 96d138b78..c93cf25aa 100644 --- a/pkg/flowcli/services/services.go +++ b/pkg/flowcli/services/services.go @@ -35,7 +35,6 @@ type Services struct { Collections *Collections Project *Project Blocks *Blocks - Config *Config } // NewServices returns a new services collection for a project, @@ -54,6 +53,5 @@ func NewServices( Collections: NewCollections(gateway, proj, logger), Project: NewProject(gateway, proj, logger), Blocks: NewBlocks(gateway, proj, logger), - Config: NewConfig(gateway, proj, logger), } } From 5605c7aa803b7471db2de310d8796c5ea368878c Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 07:36:03 -0400 Subject: [PATCH 127/171] add account changed to proj accounts --- internal/config/add-account.go | 10 ++++++++-- pkg/flowcli/config/parsers.go | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index f54948c77..a98d2b35f 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -81,7 +81,13 @@ var AddAccountCommand = &command.Command{ return nil, err } - p.Config().Accounts.AddOrUpdate(account.Name, *account) + acc, err := project.AccountFromConfig(*account) + if err != nil { + return nil, err + } + + p.AddOrUpdateAccount(acc) + err = p.SaveDefault() if err != nil { return nil, err @@ -121,7 +127,7 @@ func flagsToAccountData(flags flagsAddAccount) (map[string]string, bool, error) "address": flags.Address, "keyIndex": flags.KeyIndex, "sigAlgo": flags.SigAlgo, - "hashAlg": flags.HashAlgo, + "hashAlgo": flags.HashAlgo, "key": flags.Key, }, true, nil } diff --git a/pkg/flowcli/config/parsers.go b/pkg/flowcli/config/parsers.go index 119d32fb7..62e815190 100644 --- a/pkg/flowcli/config/parsers.go +++ b/pkg/flowcli/config/parsers.go @@ -3,6 +3,7 @@ package config import ( "fmt" "strconv" + "strings" "github.com/onflow/flow-go-sdk/crypto" @@ -39,7 +40,7 @@ func StringToAccount( SigAlgo: crypto.StringToSignatureAlgorithm(sigAlgo), HashAlgo: crypto.StringToHashAlgorithm(hashAlgo), Context: map[string]string{ - PrivateKeyField: parsedKey.String(), + PrivateKeyField: strings.ReplaceAll(parsedKey.String(), "0x", ""), }, } From 9eec3f48a8c28d9fe4902c34e71b34951765f4a9 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 07:52:02 -0400 Subject: [PATCH 128/171] accounts add removed fixed --- internal/config/remove.go | 21 +++++++++++---------- pkg/flowcli/project/project.go | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/internal/config/remove.go b/internal/config/remove.go index 4ccb88f6b..927fb3150 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -49,6 +49,7 @@ var RemoveCommand = &command.Command{ ) (command.Result, error) { resource := args[0] name := args[1] + var result *ConfigResult p, err := project.Load(globalFlags.ConfigPath) if err != nil { @@ -62,14 +63,14 @@ var RemoveCommand = &command.Command{ name = output.RemoveAccountPrompt(conf.Accounts) } - err = conf.Accounts.Remove(name) + err = p.RemoveAccount(name) if err != nil { return nil, err } - return &ConfigResult{ + result = &ConfigResult{ result: "account removed", - }, nil + } case "deployment": accountName, networkName := output.RemoveDeploymentPrompt(conf.Deployments) @@ -79,9 +80,9 @@ var RemoveCommand = &command.Command{ return nil, err } - return &ConfigResult{ + result = &ConfigResult{ result: "deployment removed", - }, nil + } case "contract": if name == "" { @@ -93,9 +94,9 @@ var RemoveCommand = &command.Command{ return nil, err } - return &ConfigResult{ + result = &ConfigResult{ result: "contract removed", - }, nil + } case "network": if name == "" { @@ -107,9 +108,9 @@ var RemoveCommand = &command.Command{ return nil, err } - return &ConfigResult{ + result = &ConfigResult{ result: "network removed", - }, nil + } } err = p.SaveDefault() @@ -117,6 +118,6 @@ var RemoveCommand = &command.Command{ return nil, err } - return nil, nil + return result, nil }, } diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index da9668972..6763f8e3d 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -243,6 +243,22 @@ func (p *Project) AddOrUpdateAccount(account *Account) { p.accounts = append(p.accounts, account) } +// RemoveAccount removes an account from configuration +func (p *Project) RemoveAccount(name string) error { + account := p.AccountByName(name) + if account == nil { + return fmt.Errorf("account named %s does not exist in configuration", name) + } + + for i, account := range p.accounts { + if account.name == name { + (*p).accounts = append(p.accounts[0:i], p.accounts[i+1:]...) // remove item + } + } + + return nil +} + // AccountByAddress returns an account by address. func (p *Project) AccountByAddress(address string) *Account { for _, account := range p.accounts { From 7e4991da58746cc3b40e86801e5a7bf1c2448ba0 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 08:09:44 -0400 Subject: [PATCH 129/171] add network fix --- internal/config/add-network.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/config/add-network.go b/internal/config/add-network.go index 7ddce8695..b1f3c484c 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -66,9 +66,7 @@ var AddNetworkCommand = &command.Command{ networkData = output.NewNetworkPrompt() } - networkData = output.NewNetworkPrompt() network := config.StringToNetwork(networkData["name"], networkData["host"]) - p.Config().Networks.AddOrUpdate(network.Name, network) err = p.SaveDefault() From d954d6c0e55a94e8070ddda385d6a797817c3803 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Tue, 27 Apr 2021 08:50:12 -0400 Subject: [PATCH 130/171] divided remove in separate commands --- internal/config/add-contract.go | 1 - internal/config/config.go | 2 +- internal/config/remove-account.go | 62 ++++++++++++++++ internal/config/remove-contract.go | 61 ++++++++++++++++ internal/config/remove-deployment.go | 63 ++++++++++++++++ internal/config/remove-network.go | 61 ++++++++++++++++ internal/config/remove.go | 105 ++------------------------- pkg/flowcli/config/config.go | 3 +- 8 files changed, 257 insertions(+), 101 deletions(-) create mode 100644 internal/config/remove-account.go create mode 100644 internal/config/remove-contract.go create mode 100644 internal/config/remove-deployment.go create mode 100644 internal/config/remove-network.go diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index 93e62d481..6909baf6c 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -67,7 +67,6 @@ var AddContractCommand = &command.Command{ contractData = output.NewContractPrompt() } - contractData = output.NewContractPrompt() contracts := config.StringToContracts( contractData["name"], contractData["source"], diff --git a/internal/config/config.go b/internal/config/config.go index 8e90d4985..6f6a52ef9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -31,7 +31,7 @@ var Cmd = &cobra.Command{ func init() { //InitCommand.AddToParent(Cmd) Cmd.AddCommand(AddCmd) - RemoveCommand.AddToParent(Cmd) + Cmd.AddCommand(RemoveCmd) } // ConfigResult result from configuration diff --git a/internal/config/remove-account.go b/internal/config/remove-account.go new file mode 100644 index 000000000..ccfe36b2f --- /dev/null +++ b/internal/config/remove-account.go @@ -0,0 +1,62 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsRemoveAccount struct{} + +var removeAccountFlags = flagsRemoveAccount{} + +var RemoveAccountCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "account ", + Short: "Remove account from configuration", + Example: "flow config remove account Foo", + Args: cobra.MaximumNArgs(1), + }, + Flags: &removeAccountFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + conf := p.Config() + + name := "" + if len(args) == 1 { + name = args[0] + } else { + name = output.RemoveAccountPrompt(conf.Accounts) + } + + err = p.RemoveAccount(name) + if err != nil { + return nil, err + } + + err = p.SaveDefault() + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "account removed", + }, nil + }, +} + +func init() { + RemoveAccountCommand.AddToParent(RemoveCmd) +} diff --git a/internal/config/remove-contract.go b/internal/config/remove-contract.go new file mode 100644 index 000000000..af82ca676 --- /dev/null +++ b/internal/config/remove-contract.go @@ -0,0 +1,61 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsRemoveContract struct{} + +var removeContractFlags = flagsRemoveContract{} + +var RemoveContractCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "contract ", + Short: "Remove contract from configuration", + Example: "flow config remove contract Foo", + Args: cobra.MaximumNArgs(1), + }, + Flags: &removeContractFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + + name := "" + if len(args) == 1 { + name = args[0] + } else { + name = output.RemoveContractPrompt(p.Config().Contracts) + } + + err = p.Config().Contracts.Remove(name) + if err != nil { + return nil, err + } + + err = p.SaveDefault() + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "contract removed", + }, nil + }, +} + +func init() { + RemoveContractCommand.AddToParent(RemoveCmd) +} diff --git a/internal/config/remove-deployment.go b/internal/config/remove-deployment.go new file mode 100644 index 000000000..6255c75ab --- /dev/null +++ b/internal/config/remove-deployment.go @@ -0,0 +1,63 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsRemoveDeployment struct{} + +var removeDeploymentFlags = flagsRemoveDeployment{} + +var RemoveDeploymentCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "deployment ", + Short: "Remove deployment from configuration", + Example: "flow config remove deployment Foo testnet", + Args: cobra.MaximumNArgs(2), + }, + Flags: &removeDeploymentFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + + account := "" + network := "" + if len(args) == 2 { + account = args[0] + network = args[1] + } else { + account, network = output.RemoveDeploymentPrompt(p.Config().Deployments) + } + + err = p.Config().Deployments.Remove(account, network) + if err != nil { + return nil, err + } + + err = p.SaveDefault() + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "deployment removed", + }, nil + }, +} + +func init() { + RemoveDeploymentCommand.AddToParent(RemoveCmd) +} diff --git a/internal/config/remove-network.go b/internal/config/remove-network.go new file mode 100644 index 000000000..9a196f145 --- /dev/null +++ b/internal/config/remove-network.go @@ -0,0 +1,61 @@ +package config + +import ( + "fmt" + + "github.com/onflow/flow-cli/internal/command" + "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/spf13/cobra" +) + +type flagsRemoveNetwork struct{} + +var removeNetworkFlags = flagsRemoveNetwork{} + +var RemoveNetworkCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "network ", + Short: "Remove network from configuration", + Example: "flow config remove network Foo", + Args: cobra.MaximumNArgs(1), + }, + Flags: &removeNetworkFlags, + Run: func( + cmd *cobra.Command, + args []string, + globalFlags command.GlobalFlags, + services *services.Services, + ) (command.Result, error) { + p, err := project.Load(globalFlags.ConfigPath) + if err != nil { + return nil, fmt.Errorf("configuration does not exists") + } + + name := "" + if len(args) == 1 { + name = args[0] + } else { + name = output.RemoveNetworkPrompt(p.Config().Networks) + } + + err = p.Config().Networks.Remove(name) + if err != nil { + return nil, err + } + + err = p.SaveDefault() + if err != nil { + return nil, err + } + + return &ConfigResult{ + result: "network removed", + }, nil + }, +} + +func init() { + RemoveNetworkCommand.AddToParent(RemoveCmd) +} diff --git a/internal/config/remove.go b/internal/config/remove.go index 927fb3150..0e2379b5e 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -19,105 +19,14 @@ package config import ( - "fmt" - - "github.com/onflow/flow-cli/internal/command" - "github.com/onflow/flow-cli/pkg/flowcli/output" - "github.com/onflow/flow-cli/pkg/flowcli/project" - "github.com/onflow/flow-cli/pkg/flowcli/services" "github.com/spf13/cobra" ) -type flagsRemove struct{} - -var removeFlags = flagsRemove{} - -var RemoveCommand = &command.Command{ - Cmd: &cobra.Command{ - Use: "remove ", - Short: "Remove resource from configuration", - Example: "flow config remove account", - ValidArgs: []string{"account", "contract", "deployment", "network"}, - Args: cobra.ExactArgs(2), - }, - Flags: &removeFlags, - Run: func( - cmd *cobra.Command, - args []string, - globalFlags command.GlobalFlags, - services *services.Services, - ) (command.Result, error) { - resource := args[0] - name := args[1] - var result *ConfigResult - - p, err := project.Load(globalFlags.ConfigPath) - if err != nil { - return nil, fmt.Errorf("configuration does not exists") - } - conf := p.Config() - - switch resource { - case "account": - if name == "" { - name = output.RemoveAccountPrompt(conf.Accounts) - } - - err = p.RemoveAccount(name) - if err != nil { - return nil, err - } - - result = &ConfigResult{ - result: "account removed", - } - - case "deployment": - accountName, networkName := output.RemoveDeploymentPrompt(conf.Deployments) - - err = conf.Deployments.Remove(accountName, networkName) - if err != nil { - return nil, err - } - - result = &ConfigResult{ - result: "deployment removed", - } - - case "contract": - if name == "" { - name = output.RemoveContractPrompt(conf.Contracts) - } - - err = conf.Contracts.Remove(name) - if err != nil { - return nil, err - } - - result = &ConfigResult{ - result: "contract removed", - } - - case "network": - if name == "" { - name = output.RemoveNetworkPrompt(conf.Networks) - } - - err = conf.Networks.Remove(name) - if err != nil { - return nil, err - } - - result = &ConfigResult{ - result: "network removed", - } - } - - err = p.SaveDefault() - if err != nil { - return nil, err - } - - return result, nil - }, +var RemoveCmd = &cobra.Command{ + Use: "remove ", + Short: "Remove resource from configuration", + Example: "flow config remove account", + ValidArgs: []string{"account", "contract", "deployment", "network"}, + Args: cobra.ExactArgs(1), + TraverseChildren: true, } diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 1f24d47d8..aa5a4376d 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -324,7 +324,8 @@ func (d *Deployments) GetByAccountAndNetwork(account string, network string) Dep // AddOrUpdate add new or update if already present func (d *Deployments) AddOrUpdate(deployment Deploy) { for i, existingDeployment := range *d { - if existingDeployment.Account == deployment.Account { + if existingDeployment.Account == deployment.Account && + existingDeployment.Network == deployment.Network { (*d)[i] = deployment return } From 1cd0b6cafd8343d49c958bf6333846706f8699c5 Mon Sep 17 00:00:00 2001 From: Peter Siemens Date: Tue, 27 Apr 2021 20:31:41 -0700 Subject: [PATCH 131/171] Use default key as proposal key in Transactions.Send --- pkg/flowcli/services/transactions.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/flowcli/services/transactions.go b/pkg/flowcli/services/transactions.go index 4b1f14c52..d1ab40cf9 100644 --- a/pkg/flowcli/services/transactions.go +++ b/pkg/flowcli/services/transactions.go @@ -244,11 +244,13 @@ func (t *Transactions) Send( return nil, nil, fmt.Errorf("signer account: [%s] doesn't exists in configuration", signerName) } + signerKeyIndex := signerAccount.DefaultKey().Index() + tx, err := t.Build( signerName, []string{signerName}, signerName, - 0, // default 0 key + signerKeyIndex, transactionFilename, args, argsJSON, From 4ea7142b40cead18f657c970774accf7cf706114 Mon Sep 17 00:00:00 2001 From: Peter Siemens Date: Tue, 27 Apr 2021 20:38:34 -0700 Subject: [PATCH 132/171] Use default key in transaction.SetProposer --- pkg/flowcli/services/accounts.go | 2 +- pkg/flowcli/services/project.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index 5c1a6a5bc..e36e78b1f 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -417,7 +417,7 @@ func (a *Accounts) prepareTransaction( } tx.SetBlockReference(block). - SetProposer(proposer, 0) + SetProposer(proposer, account.DefaultKey().Index()) tx, err = tx.Sign() if err != nil { diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 230286f9f..acd6d4ea4 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -184,7 +184,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er } tx.SetBlockReference(block). - SetProposer(targetAccountInfo, 0) + SetProposer(targetAccountInfo, targetAccount.DefaultKey().Index()) tx, err = tx.Sign() if err != nil { From b2c663c3bfbff0e9c6c5cb40b228fb701877384c Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 13:29:17 -0400 Subject: [PATCH 133/171] handle prompt exit --- pkg/flowcli/output/prompt.go | 98 +++++++++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 17 deletions(-) diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index 887d13f5f..206b2c84e 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -21,6 +21,7 @@ package output import ( "fmt" "net/url" + "os" "github.com/onflow/flow-cli/pkg/flowcli/util" @@ -108,7 +109,11 @@ func namePrompt() string { }, } - name, _ := namePrompt.Run() + name, err := namePrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } + return name } @@ -121,7 +126,11 @@ func addressPrompt() string { }, } - address, _ := addressPrompt.Run() + address, err := addressPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } + return address } @@ -135,7 +144,11 @@ func contractAliasPrompt(contractName string) (string, string) { ), Items: []string{"No", "Yes, Emulator Alias", "Yes, Testnet Alias"}, } - i, answer, _ := aliasesPrompt.Run() + i, answer, err := aliasesPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } + return answer, networks[i] } @@ -144,7 +157,10 @@ func contractPrompt(contractNames []string) string { Label: "Choose contract you wish to deploy", Items: contractNames, } - _, contractName, _ := contractPrompt.Run() + _, contractName, err := contractPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } return contractName } @@ -154,12 +170,17 @@ func addAnotherContractToDeploymentPrompt() bool { Label: "Do you wish to add another contract for deployment?", Items: []string{"No", "Yes"}, } - _, addMore, _ := addContractPrompt.Run() + _, addMore, err := addContractPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } + return addMore == "Yes" } func NewAccountPrompt() map[string]string { accountData := make(map[string]string) + var err error accountData["name"] = namePrompt() accountData["address"] = addressPrompt() @@ -168,13 +189,19 @@ func NewAccountPrompt() map[string]string { Label: "Signature algorithm", Items: []string{"ECDSA_P256", "ECDSA_secp256k1"}, } - _, accountData["sigAlgo"], _ = sigAlgoPrompt.Run() + _, accountData["sigAlgo"], err = sigAlgoPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } hashAlgoPrompt := promptui.Select{ Label: "Hashing algorithm", Items: []string{"SHA3_256", "SHA2_256"}, } - _, accountData["hashAlgo"], _ = hashAlgoPrompt.Run() + _, accountData["hashAlgo"], err = hashAlgoPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } keyPrompt := promptui.Prompt{ Label: "Private key", @@ -183,7 +210,10 @@ func NewAccountPrompt() map[string]string { return err }, } - accountData["key"], _ = keyPrompt.Run() + accountData["key"], err = keyPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } keyIndexPrompt := promptui.Prompt{ Label: "Key index (Default: 0)", @@ -193,13 +223,18 @@ func NewAccountPrompt() map[string]string { return err }, } - accountData["keyIndex"], _ = keyIndexPrompt.Run() + + accountData["keyIndex"], err = keyIndexPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } return accountData } func NewContractPrompt() map[string]string { contractData := make(map[string]string) + var err error contractData["name"] = namePrompt() @@ -213,7 +248,10 @@ func NewContractPrompt() map[string]string { return nil }, } - contractData["source"], _ = sourcePrompt.Run() + contractData["source"], err = sourcePrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } aliasAnswer, network := contractAliasPrompt(contractData["name"]) for aliasAnswer != "No" { @@ -228,6 +266,8 @@ func NewContractPrompt() map[string]string { func NewNetworkPrompt() map[string]string { networkData := make(map[string]string) + var err error + networkData["name"] = namePrompt() hostPrompt := promptui.Prompt{ @@ -237,7 +277,10 @@ func NewNetworkPrompt() map[string]string { return err }, } - networkData["host"], _ = hostPrompt.Run() + networkData["host"], err = hostPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } return networkData } @@ -248,6 +291,7 @@ func NewDeploymentPrompt( contracts config.Contracts, ) map[string]interface{} { deploymentData := make(map[string]interface{}) + var err error networkNames := make([]string, 0) for _, network := range networks { @@ -258,7 +302,10 @@ func NewDeploymentPrompt( Label: "Choose network for deployment", Items: networkNames, } - _, deploymentData["network"], _ = networkPrompt.Run() + _, deploymentData["network"], err = networkPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } accountNames := make([]string, 0) for _, account := range accounts { @@ -269,7 +316,10 @@ func NewDeploymentPrompt( Label: "Choose an account to deploy to", Items: accountNames, } - _, deploymentData["account"], _ = accountPrompt.Run() + _, deploymentData["account"], err = accountPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } contractNames := make([]string, 0) for _, contract := range contracts { @@ -307,7 +357,10 @@ func RemoveAccountPrompt(accounts config.Accounts) string { Items: accountNames, } - _, name, _ := namePrompt.Run() + _, name, err := namePrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } return name } @@ -337,7 +390,10 @@ func RemoveDeploymentPrompt(deployments config.Deployments) (account string, net Items: deploymentNames, } - index, _, _ := deployPrompt.Run() + index, _, err := deployPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } return deployments[index].Account, deployments[index].Network } @@ -354,7 +410,11 @@ func RemoveContractPrompt(contracts config.Contracts) string { Items: contractNames, } - _, name, _ := contractPrompt.Run() + _, name, err := contractPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } + return name } @@ -370,6 +430,10 @@ func RemoveNetworkPrompt(networks config.Networks) string { Items: networkNames, } - _, name, _ := networkPrompt.Run() + _, name, err := networkPrompt.Run() + if err == promptui.ErrInterrupt { + os.Exit(-1) + } + return name } From 8978b3eec3cc1c2b9989dadad98f138aec040203 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 13:29:25 -0400 Subject: [PATCH 134/171] add network error fix --- internal/config/add-network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/config/add-network.go b/internal/config/add-network.go index b1f3c484c..6e9332243 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -92,7 +92,7 @@ func flagsToNetworkData(flags flagsAddNetwork) (map[string]string, bool, error) if flags.Name == "" { return nil, true, fmt.Errorf("name must be provided") } else if flags.Host == "" { - return nil, true, fmt.Errorf("contract file name must be provided") + return nil, true, fmt.Errorf("host must be provided") } _, err := url.ParseRequestURI(flags.Host) From c776710a62456bd8dc2034d8503a93cf795dbb48 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 13:55:41 -0400 Subject: [PATCH 135/171] add contract alias fix --- pkg/flowcli/config/config.go | 3 ++- pkg/flowcli/output/prompt.go | 30 ++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index aa5a4376d..1931b0b7f 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -232,7 +232,8 @@ func (c *Contracts) GetByNetwork(network string) Contracts { // AddOrUpdate add new or update if already present func (c *Contracts) AddOrUpdate(name string, contract Contract) { for i, existingContract := range *c { - if existingContract.Name == name { + if existingContract.Name == name && + existingContract.Network == contract.Network { (*c)[i] = contract return } diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index 206b2c84e..afa9186aa 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -135,7 +135,7 @@ func addressPrompt() string { } func contractAliasPrompt(contractName string) (string, string) { - networks := []string{"emulator", "testnet"} + networks := []string{"", "emulator", "testnet"} aliasesPrompt := promptui.Select{ Label: fmt.Sprintf( @@ -253,13 +253,31 @@ func NewContractPrompt() map[string]string { os.Exit(-1) } - aliasAnswer, network := contractAliasPrompt(contractData["name"]) - for aliasAnswer != "No" { - aliasAddress := addressPrompt() - contractData[network] = aliasAddress + emulatorAliasPrompt := promptui.Prompt{ + Label: "Enter emulator alias, if exists", + Validate: func(s string) error { + if s != "" { + _, err := config.StringToAddress(s) + return err + } + + return nil + }, + } + contractData["emulator"], _ = emulatorAliasPrompt.Run() - aliasAnswer, network = contractAliasPrompt(contractData["name"]) + testnetAliasPrompt := promptui.Prompt{ + Label: "Enter testnet alias, if exists", + Validate: func(s string) error { + if s != "" { + _, err := config.StringToAddress(s) + return err + } + + return nil + }, } + contractData["testnet"], _ = testnetAliasPrompt.Run() return contractData } From 00922e074f4ccb6d4e2b111a689c151f0083b336 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 14:13:27 -0400 Subject: [PATCH 136/171] check if is not simple contract --- pkg/flowcli/config/json/contract.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/config/json/contract.go b/pkg/flowcli/config/json/contract.go index b19fc0dc0..0b0f2abdd 100644 --- a/pkg/flowcli/config/json/contract.go +++ b/pkg/flowcli/config/json/contract.go @@ -68,7 +68,7 @@ func transformContractsToJSON(contracts config.Contracts) jsonContracts { } } else { // if advanced config // check if we already created for this name then add or create - if _, exists := jsonContracts[c.Name]; exists { + if _, exists := jsonContracts[c.Name]; exists && jsonContracts[c.Name].Advanced.Aliases != nil { jsonContracts[c.Name].Advanced.Aliases[c.Network] = c.Alias } else { jsonContracts[c.Name] = jsonContract{ From 9addbecfb1f205d777ebb5ddad50656d0326a151 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 14:23:57 -0400 Subject: [PATCH 137/171] add docs --- docs/configuration.md | 3 +++ docs/manage-configuration.md | 41 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 docs/manage-configuration.md diff --git a/docs/configuration.md b/docs/configuration.md index 3352b4b53..22f4ade9a 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -14,6 +14,9 @@ Flow configuration (`flow.json`) file will contain the following properties: - A `deployments` empty object where all [deployment targets](https://docs.onflow.org/flow-cli/project-contracts/) can be defined. - A `contracts` empty object where you [define contracts](https://docs.onflow.org/flow-cli/project-contracts/) you wish to deploy. +Configuration should be managed using [manage commands](https://docs.onflow.org/flow-cli/manage-configuration/) +`flow config add` or `flow config remove`. + ## Example Project Configuration ```json diff --git a/docs/manage-configuration.md b/docs/manage-configuration.md new file mode 100644 index 000000000..32fd00d6a --- /dev/null +++ b/docs/manage-configuration.md @@ -0,0 +1,41 @@ +--- +title: Manage Flow Configuration +sidebar_title: Manage Configuration +description: How to manage Flow Configuration using CLI +--- + +Configuration should be managed by using `config add` +and `config remove` commands. Using add command will also +validate values that will be added to the configuration. + +```shell +flow config add +flow config remove +``` + +## Example Usage + +```shell +flow config add account + +Name: Admin +Address: f8d6e0586b0a20c7 +✔ ECDSA_P256 +✔ SHA3_256 +Private key: e382a0e494...9285809356 +Key index (Default: 0): 0 +``` + +### Configuration + +- Flag: `--config-path` +- Short Flag: `-f` +- Valid inputs: valid filename + +Specify a filename for the configuration files, you can provide multiple configuration +files by using `-f` flag multiple times. + + + + + From 4c3858a4c5d3733a59771b26df2fa86ce7d5cde7 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 14:30:21 -0400 Subject: [PATCH 138/171] better output --- internal/config/add-account.go | 2 +- internal/config/add-contract.go | 2 +- internal/config/add-deployment.go | 2 +- internal/config/add-network.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index a98d2b35f..d3194ed3d 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -94,7 +94,7 @@ var AddAccountCommand = &command.Command{ } return &ConfigResult{ - result: "account added", + result: fmt.Sprintf("Account %s added to the configuration", accountData["name"]), }, nil }, diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index 6909baf6c..68f8d287f 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -84,7 +84,7 @@ var AddContractCommand = &command.Command{ } return &ConfigResult{ - result: "contract added", + result: fmt.Sprintf("Contract %s added to the configuration", contractData["name"]), }, nil }, } diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index 39e530807..c4531411e 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -80,7 +80,7 @@ var AddDeploymentCommand = &command.Command{ } return &ConfigResult{ - result: "deploy added", + result: fmt.Sprintf("Deployment added to the configuration.\nYou can deploy using 'flow project deploy' command"), }, nil }, } diff --git a/internal/config/add-network.go b/internal/config/add-network.go index 6e9332243..bc1a04e71 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -75,7 +75,7 @@ var AddNetworkCommand = &command.Command{ } return &ConfigResult{ - result: "network added", + result: fmt.Sprintf("Network %s added to the configuration", networkData["name"]), }, nil }, } From 252892d1a22347755b0bdfe019250af975980db5 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 14:31:15 -0400 Subject: [PATCH 139/171] added headers --- internal/config/remove-account.go | 18 ++++++++++++++++++ internal/config/remove-contract.go | 18 ++++++++++++++++++ internal/config/remove-deployment.go | 18 ++++++++++++++++++ internal/config/remove-network.go | 18 ++++++++++++++++++ 4 files changed, 72 insertions(+) diff --git a/internal/config/remove-account.go b/internal/config/remove-account.go index ccfe36b2f..645087680 100644 --- a/internal/config/remove-account.go +++ b/internal/config/remove-account.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( diff --git a/internal/config/remove-contract.go b/internal/config/remove-contract.go index af82ca676..23d435f28 100644 --- a/internal/config/remove-contract.go +++ b/internal/config/remove-contract.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( diff --git a/internal/config/remove-deployment.go b/internal/config/remove-deployment.go index 6255c75ab..45728df31 100644 --- a/internal/config/remove-deployment.go +++ b/internal/config/remove-deployment.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( diff --git a/internal/config/remove-network.go b/internal/config/remove-network.go index 9a196f145..77a1791b7 100644 --- a/internal/config/remove-network.go +++ b/internal/config/remove-network.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( From 0471296ff5ed692d01abbacea7ff261768b87d6c Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 14:35:44 -0400 Subject: [PATCH 140/171] lint --- internal/config/add-account.go | 4 ++-- internal/config/add-contract.go | 4 ++-- internal/config/add-deployment.go | 5 +++-- internal/config/add-network.go | 4 ++-- internal/config/remove-account.go | 3 ++- internal/config/remove-contract.go | 3 ++- internal/config/remove-deployment.go | 3 ++- internal/config/remove-network.go | 3 ++- pkg/flowcli/output/prompt.go | 18 ------------------ 9 files changed, 17 insertions(+), 30 deletions(-) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index d3194ed3d..31789f376 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -21,13 +21,13 @@ package config import ( "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsAddAccount struct { diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index 68f8d287f..c0b440993 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -21,13 +21,13 @@ package config import ( "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsAddContract struct { diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index c4531411e..495a6eda3 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -21,12 +21,13 @@ package config import ( "fmt" + "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsAddDeployment struct { @@ -80,7 +81,7 @@ var AddDeploymentCommand = &command.Command{ } return &ConfigResult{ - result: fmt.Sprintf("Deployment added to the configuration.\nYou can deploy using 'flow project deploy' command"), + result: "Deployment added to the configuration.\nYou can deploy using 'flow project deploy' command", }, nil }, } diff --git a/internal/config/add-network.go b/internal/config/add-network.go index bc1a04e71..15cafb3b9 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -22,13 +22,13 @@ import ( "fmt" "net/url" - "github.com/onflow/flow-cli/pkg/flowcli/project" + "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/config" "github.com/onflow/flow-cli/pkg/flowcli/output" + "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsAddNetwork struct { diff --git a/internal/config/remove-account.go b/internal/config/remove-account.go index 645087680..6ca9625a8 100644 --- a/internal/config/remove-account.go +++ b/internal/config/remove-account.go @@ -21,11 +21,12 @@ package config import ( "fmt" + "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsRemoveAccount struct{} diff --git a/internal/config/remove-contract.go b/internal/config/remove-contract.go index 23d435f28..519d54a9f 100644 --- a/internal/config/remove-contract.go +++ b/internal/config/remove-contract.go @@ -21,11 +21,12 @@ package config import ( "fmt" + "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsRemoveContract struct{} diff --git a/internal/config/remove-deployment.go b/internal/config/remove-deployment.go index 45728df31..19ae40e43 100644 --- a/internal/config/remove-deployment.go +++ b/internal/config/remove-deployment.go @@ -21,11 +21,12 @@ package config import ( "fmt" + "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsRemoveDeployment struct{} diff --git a/internal/config/remove-network.go b/internal/config/remove-network.go index 77a1791b7..a4cf837d2 100644 --- a/internal/config/remove-network.go +++ b/internal/config/remove-network.go @@ -21,11 +21,12 @@ package config import ( "fmt" + "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/onflow/flow-cli/pkg/flowcli/project" "github.com/onflow/flow-cli/pkg/flowcli/services" - "github.com/spf13/cobra" ) type flagsRemoveNetwork struct{} diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index afa9186aa..14214f53f 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -134,24 +134,6 @@ func addressPrompt() string { return address } -func contractAliasPrompt(contractName string) (string, string) { - networks := []string{"", "emulator", "testnet"} - - aliasesPrompt := promptui.Select{ - Label: fmt.Sprintf( - "Does contract [%s] have any additional aliases: \nYou can read about aliases here: https://docs.onflow.org/flow-cli/project-contracts/", // todo check - contractName, - ), - Items: []string{"No", "Yes, Emulator Alias", "Yes, Testnet Alias"}, - } - i, answer, err := aliasesPrompt.Run() - if err == promptui.ErrInterrupt { - os.Exit(-1) - } - - return answer, networks[i] -} - func contractPrompt(contractNames []string) string { contractPrompt := promptui.Select{ Label: "Choose contract you wish to deploy", From a44f21d623eb89ac8d475347ab431d86ecb0eacd Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 14:44:51 -0400 Subject: [PATCH 141/171] conflict fixes --- internal/config/add-account.go | 2 +- internal/config/add-contract.go | 2 +- internal/config/add-deployment.go | 2 +- internal/config/add-network.go | 2 +- internal/config/remove-account.go | 2 +- internal/config/remove-contract.go | 2 +- internal/config/remove-deployment.go | 2 +- internal/config/remove-network.go | 2 +- pkg/flowcli/config/config.go | 1 + pkg/flowcli/output/prompt.go | 2 -- pkg/flowcli/project/project.go | 2 +- pkg/flowcli/services/accounts.go | 2 +- pkg/flowcli/services/project.go | 2 +- pkg/flowcli/services/transactions.go | 2 +- 14 files changed, 13 insertions(+), 14 deletions(-) diff --git a/internal/config/add-account.go b/internal/config/add-account.go index 31789f376..34beac188 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -55,7 +55,7 @@ var AddAccountCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/add-contract.go b/internal/config/add-contract.go index c0b440993..8f6d2156f 100644 --- a/internal/config/add-contract.go +++ b/internal/config/add-contract.go @@ -53,7 +53,7 @@ var AddContractCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/add-deployment.go b/internal/config/add-deployment.go index 495a6eda3..0bd9ee0f4 100644 --- a/internal/config/add-deployment.go +++ b/internal/config/add-deployment.go @@ -52,7 +52,7 @@ var AddDeploymentCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/add-network.go b/internal/config/add-network.go index 15cafb3b9..e76729516 100644 --- a/internal/config/add-network.go +++ b/internal/config/add-network.go @@ -52,7 +52,7 @@ var AddNetworkCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/remove-account.go b/internal/config/remove-account.go index 6ca9625a8..95789c231 100644 --- a/internal/config/remove-account.go +++ b/internal/config/remove-account.go @@ -47,7 +47,7 @@ var RemoveAccountCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/remove-contract.go b/internal/config/remove-contract.go index 519d54a9f..62ae3f8d2 100644 --- a/internal/config/remove-contract.go +++ b/internal/config/remove-contract.go @@ -47,7 +47,7 @@ var RemoveContractCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/remove-deployment.go b/internal/config/remove-deployment.go index 19ae40e43..02c7fa831 100644 --- a/internal/config/remove-deployment.go +++ b/internal/config/remove-deployment.go @@ -47,7 +47,7 @@ var RemoveDeploymentCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/internal/config/remove-network.go b/internal/config/remove-network.go index a4cf837d2..ba08a216c 100644 --- a/internal/config/remove-network.go +++ b/internal/config/remove-network.go @@ -47,7 +47,7 @@ var RemoveNetworkCommand = &command.Command{ globalFlags command.GlobalFlags, services *services.Services, ) (command.Result, error) { - p, err := project.Load(globalFlags.ConfigPath) + p, err := project.Load(globalFlags.ConfigPaths) if err != nil { return nil, fmt.Errorf("configuration does not exists") } diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 3f7649cc7..bf535bfab 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -21,6 +21,7 @@ package config import ( "errors" "fmt" + "os" "github.com/onflow/cadence" diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index 570652f01..766ccc966 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -98,7 +98,6 @@ func ApproveTransactionPrompt(transaction *project.Transaction) bool { return result == "Yes" } - func AutocompletionPrompt() (string, string) { prompt := promptui.Select{ Label: "❓ Select your shell (you can run 'echo $SHELL' to find out)", @@ -128,7 +127,6 @@ PS> flow config setup-completions powershell > flow.ps1 return shell, os } - func namePrompt() string { namePrompt := promptui.Prompt{ Label: "Name", diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index 66d0e2472..b3d50f66c 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -75,7 +75,7 @@ func Load(configFilePaths []string) (*Project, error) { // SaveDefault saves configuration to default path func (p *Project) SaveDefault() error { - return p.Save(DefaultConfigPath) + return p.Save(config.DefaultPath) } // Save saves the project configuration to the given path. diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index fa122d11b..1635c71c1 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -420,7 +420,7 @@ func (a *Accounts) prepareTransaction( } tx.SetBlockReference(block). - SetProposer(proposer, account.DefaultKey().Index()) + SetProposer(proposer, account.Key().Index()) tx, err = tx.Sign() if err != nil { diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 57caa555a..7062dfd6a 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -207,7 +207,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er } tx.SetBlockReference(block). - SetProposer(targetAccountInfo, targetAccount.DefaultKey().Index()) + SetProposer(targetAccountInfo, targetAccount.Key().Index()) tx, err = tx.Sign() if err != nil { diff --git a/pkg/flowcli/services/transactions.go b/pkg/flowcli/services/transactions.go index a2421ab67..f29fe5e19 100644 --- a/pkg/flowcli/services/transactions.go +++ b/pkg/flowcli/services/transactions.go @@ -244,7 +244,7 @@ func (t *Transactions) Send( return nil, nil, fmt.Errorf("signer account: [%s] doesn't exists in configuration", signerName) } - signerKeyIndex := signerAccount.DefaultKey().Index() + signerKeyIndex := signerAccount.Key().Index() tx, err := t.Build( signerName, From 33e089f63150d748d93855341bd5923cc79da5dd Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:09:52 -0400 Subject: [PATCH 142/171] remove config --- cmd/flow/main.go | 1 - internal/config/config.go | 1 - 2 files changed, 2 deletions(-) diff --git a/cmd/flow/main.go b/cmd/flow/main.go index 83417e355..45af7a606 100644 --- a/cmd/flow/main.go +++ b/cmd/flow/main.go @@ -61,7 +61,6 @@ func main() { cmd.AddCommand(blocks.Cmd) cmd.AddCommand(collections.Cmd) cmd.AddCommand(project.Cmd) - cmd.AddCommand(config.Cmd) command.InitFlags(cmd) diff --git a/internal/config/config.go b/internal/config/config.go index 6f6a52ef9..97be054e5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -29,7 +29,6 @@ var Cmd = &cobra.Command{ } func init() { - //InitCommand.AddToParent(Cmd) Cmd.AddCommand(AddCmd) Cmd.AddCommand(RemoveCmd) } From 116b27b174513bd9a15f485fb82e65bf68d2b3a4 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:15:33 -0400 Subject: [PATCH 143/171] global config renamed --- docs/initialize-configuration.md | 8 ++++---- pkg/flowcli/config/config.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/initialize-configuration.md b/docs/initialize-configuration.md index c480ddd64..b3d6ef93f 100644 --- a/docs/initialize-configuration.md +++ b/docs/initialize-configuration.md @@ -36,7 +36,7 @@ or by removing the configuration file first. ## Global Configuration -Flow supports global configuration which is a `.flow.json` file saved in your home +Flow supports global configuration which is a `flow.json` file saved in your home directory and loaded as the first configuration file wherever you execute the CLI command. Please be aware that global configuration has the lowest priority and is overwritten @@ -48,9 +48,9 @@ You can generate a global configuration using `--global` flag. Command example: `flow init --global`. Global flow configuration is saved as: -- MacOs: `~/.flow.json` -- Linux: `~/.flow.json` -- Windows: `C:\Users\$USER\.flow.json` +- MacOs: `~/flow.json` +- Linux: `~/flow.json` +- Windows: `C:\Users\$USER\flow.json` ## Flags diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index bf535bfab..e5c056435 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -177,7 +177,7 @@ func GlobalPath() string { return "" } - return fmt.Sprintf("%s/.%s", dirname, DefaultPath) + return fmt.Sprintf("%s/%s", dirname, DefaultPath) } // DefaultPaths determines default paths for configuration From 33b8386c198ceab7dbe15f4706a1c01c3824d147 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:28:10 -0400 Subject: [PATCH 144/171] remove valid args --- internal/config/add.go | 1 - internal/config/remove.go | 1 - 2 files changed, 2 deletions(-) diff --git a/internal/config/add.go b/internal/config/add.go index a84e16937..c55ae7c4c 100644 --- a/internal/config/add.go +++ b/internal/config/add.go @@ -26,7 +26,6 @@ var AddCmd = &cobra.Command{ Use: "add ", Short: "Add resource to configuration", Example: "flow config add account", - ValidArgs: []string{"account", "contract", "deployment", "network"}, Args: cobra.ExactArgs(1), TraverseChildren: true, } diff --git a/internal/config/remove.go b/internal/config/remove.go index 0e2379b5e..a39e92795 100644 --- a/internal/config/remove.go +++ b/internal/config/remove.go @@ -26,7 +26,6 @@ var RemoveCmd = &cobra.Command{ Use: "remove ", Short: "Remove resource from configuration", Example: "flow config remove account", - ValidArgs: []string{"account", "contract", "deployment", "network"}, Args: cobra.ExactArgs(1), TraverseChildren: true, } From 4d413a3fc849a11b0cdedcbb2ba5a019b8897e0a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:30:17 -0400 Subject: [PATCH 145/171] flag texts and renamed flag --- docs/manage-configuration.md | 2 +- internal/config/add-account.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/manage-configuration.md b/docs/manage-configuration.md index 32fd00d6a..6f46f5e5e 100644 --- a/docs/manage-configuration.md +++ b/docs/manage-configuration.md @@ -1,7 +1,7 @@ --- title: Manage Flow Configuration sidebar_title: Manage Configuration -description: How to manage Flow Configuration using CLI +description: How to configure the Flow CLI --- Configuration should be managed by using `config add` diff --git a/internal/config/add-account.go b/internal/config/add-account.go index 34beac188..0e9ea478e 100644 --- a/internal/config/add-account.go +++ b/internal/config/add-account.go @@ -34,9 +34,9 @@ type flagsAddAccount struct { Name string `flag:"name" info:"Name for the account"` Address string `flag:"address" info:"Account address"` KeyIndex string `default:"0" flag:"key-index" info:"Account key index"` - SigAlgo string `default:"ECDSA_P256" flag:"sig-algo" info:"Account key signature algorithm"` - HashAlgo string `default:"SHA3_256" flag:"hash-algo" info:"Account hash used for the digest"` - Key string `flag:"key" info:"Account private key"` + SigAlgo string `default:"ECDSA_P256" flag:"sig-algo" info:"Signature algorithm of this account key"` + HashAlgo string `default:"SHA3_256" flag:"hash-algo" info:"Hash algorithm to pair with this account key"` + Key string `flag:"private-key" info:"Account private key"` } var addAccountFlags = flagsAddAccount{} From 43ff6d7219aeb94d77e0cfcd423415894eb71bd3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:39:16 -0400 Subject: [PATCH 146/171] add init args to docs --- docs/deploy-project-contracts.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/deploy-project-contracts.md b/docs/deploy-project-contracts.md index 2e0aff747..d22afb616 100644 --- a/docs/deploy-project-contracts.md +++ b/docs/deploy-project-contracts.md @@ -61,6 +61,33 @@ pub contract KittyItems { } ``` +## Initialization Arguments +Deploying contracts that take initialization arguments +can be achieved with adding those arguments to the configuration. + +Each deployment can be specified as an object containing +`name` and `args` key specifying arguments to be +used during the deployment. Example: + +``` +... + "deployments": { + "testnet": { + "my-testnet-account": [ + "NonFungibleToken", { + "name": "KittyItems", + "args": [{ + "name": "supply", + "type": "UInt", + "value": "10", + }] + }] + } + } +... +``` + + ⚠️ Warning: before proceeding, we recommend reading the [Flow CLI security guidelines](https://docs.onflow.org/flow-cli/security/) to learn about the best practices for private key storage. From 2ebd54d20eeac980b3950462b12d2baa408041bb Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:55:28 -0400 Subject: [PATCH 147/171] docs fixes --- docs/configuration.md | 3 --- docs/security.md | 8 ++++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index d404ba972..2b143de2c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -14,9 +14,6 @@ Flow configuration (`flow.json`) file will contain the following properties: - A `deployments` empty object where all [deployment targets](https://docs.onflow.org/flow-cli/project-contracts/) can be defined. - A `contracts` empty object where you [define contracts](https://docs.onflow.org/flow-cli/project-contracts/) you wish to deploy. -Configuration should be managed using [manage commands](https://docs.onflow.org/flow-cli/manage-configuration/) -`flow config add` or `flow config remove`. - ## Example Project Configuration ```json diff --git a/docs/security.md b/docs/security.md index 936272f71..3932c8252 100644 --- a/docs/security.md +++ b/docs/security.md @@ -78,9 +78,13 @@ PRIVATE_KEY=key flow project deploy ### Private Dotenv File -The CLI will load environment variables defined a .env file in the active directory, if one exists. These variables can be substituted inside flow.json, just like any other environment variable. +The CLI will load environment variables defined in the `.env` file in the active directory, if one exists. +These variables can be substituted inside the `flow.json`, +just like any other environment variable. -⚠️ You should never commit `.env` to source control, especially if it contains sensitive information like a private key. +⚠️ You should never commit `.env` to source control, +especially if it contains sensitive information +like a private key. Example `.env` file: ```bash From 0dca986b4b83b654939fcdbc7d502dfdb9fa21f2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 15:55:34 -0400 Subject: [PATCH 148/171] release notes --- docs/developer-updates/release-notes-v19.md | 105 ++++++++++++++++++++ docs/developer-updates/v17.md | 30 ------ 2 files changed, 105 insertions(+), 30 deletions(-) create mode 100644 docs/developer-updates/release-notes-v19.md delete mode 100644 docs/developer-updates/v17.md diff --git a/docs/developer-updates/release-notes-v19.md b/docs/developer-updates/release-notes-v19.md new file mode 100644 index 000000000..f324f3be7 --- /dev/null +++ b/docs/developer-updates/release-notes-v19.md @@ -0,0 +1,105 @@ +## ⬆️ Install or Upgrade + +Follow the [Flow CLI installation guide](https://docs.onflow.org/flow-cli/install/) for instructions on how to install or upgrade the CLI. + +## ⭐ Features + +### Project Deployment with Contract Initialization Arguments +Project deployment was enhanced and it now supports providing initialization +arguments during the deployment of contracts. It is easy to specify all +the arguments in the configuration like so: + +``` +... + "deployments": { + "testnet": { + "my-testnet-account": [ + "NonFungibleToken", { + "name": "KittyItems", + "args": [{ + "name": "supply", + "type": "UInt", + "value": "10", + }] + }] + } + } +... +``` + +### Network Status Command +Network status command allows you to query the status of each network and +see if the network is available. + +Example: +``` +> flow status --network testnet + +Status: 🟢 ONLINE +Network: testnet +Access Node: access.devnet.nodes.onflow.org:9000 +``` + +### Global Configuration +Flow CLI now supports global configuration which is a `flow.json` file saved in your home +directory and loaded as the first configuration file wherever you execute the CLI command. + +You can generate a global configuration using `--global` flag. + +Command example: `flow init --global`. + +Global flow configuration is saved as: +- MacOs: `~/flow.json` +- Linux: `~/flow.json` +- Windows: `C:\Users\$USER\flow.json` + +You can read more about it in [the docs](https://docs.onflow.org/flow-cli/initialize-configuration/). + +### Environment File Support + +The CLI will load environment variables defined in the +`.env` file in the active directory, if one exists. +These variables can be substituted inside the `flow.json`, +just like any other environment variable. + +Example `.env` file: +```bash +PRIVATE_KEY=123 +``` + +```json +// flow.json +{ + ... + "accounts": { + "my-testnet-account": { + "address": "3ae53cb6e3f42a79", + "keys": "$PRIVATE_KEY" + } + } + ... +} +``` + +## 🎉 Improvements + +### Default Network Without Configuration +Default network is provided even if no configuration is present which +allows you to use the CLI on even more commands without the requirement of +having a configuration pre-initialized. + +### Chain ID Removed +Chain ID property was removed from the configuration as it is not needed anymore. +With this improvement, the new configuration is less complex and shorter. + +### Multiple Keys Removed +Multiple keys were removed from the account configuration making it +less complex. Should you have a rare need of specifying multiple keys +on account you can specify multiple accounts with the same address and +different keys. This new functionality is backward compatible. + +## 🐞 Bug Fixes + +### Keys Generate JSON output +Keys generation output in JSON format was fixed and it now shows correctly +private and public keys. \ No newline at end of file diff --git a/docs/developer-updates/v17.md b/docs/developer-updates/v17.md deleted file mode 100644 index 537878300..000000000 --- a/docs/developer-updates/v17.md +++ /dev/null @@ -1,30 +0,0 @@ -# CLI Developer Update v17.0 - -The new CLI version introduces big improvements to the codebase and allows -other developers to import the `flowcli` package directly in their Go projects. - -The configuration was unified and you can now use the new configuration format for all the commands. - -The commands and flags were adapted for more consistency. -The new [documentation](https://docs.onflow.org/flow-cli/) covers all the commands you can use. - -This release also includes CLI design guidelines that you -can read the [CONTRIBUTING.md](https://github.com/onflow/flow-cli/blob/master/CONTRIBUTING.md) document. - -We've also deprecated some features and improved deprecation warnings. Commands now include deprecated flags which instruct you -on how to use the command with new flags. We're aiming to wait 2 weeks before removing deprecated functionality. - -For example: - -``` -❌ Command Error: ⚠️ No longer supported: use command argument. -``` - -Improved error reporting with suggestions on how to fix the error: - -``` -❌ Error while dialing dial tcp 127.0.0.1:3569: connect: connection refused" -🙏 Make sure your emulator is running or connection address is correct. -``` - -You can find the full release notes here: {{RELEASE_NOTES}} From 323e834abf56dfe6585e92265148b89c376c0e56 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 16:14:25 -0400 Subject: [PATCH 149/171] refactor config missing error and handle not found config better --- internal/command/command.go | 6 ++---- pkg/flowcli/config/loader.go | 4 ++-- pkg/flowcli/services/accounts.go | 4 ++-- pkg/flowcli/services/project.go | 2 +- pkg/flowcli/services/scripts.go | 4 +++- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index 7bea3f51e..4a8cc8a87 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -232,17 +232,15 @@ func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (st } return proj.NetworkByName(networkFlag).Host, nil - } else if networkFlag != config.DefaultEmulatorNetwork().Name { - return "", fmt.Errorf("network not found, make sure flow configuration exists") } networks := config.DefaultNetworks() network := networks.GetByName(networkFlag) - + if network != nil { return network.Host, nil } - + return "", fmt.Errorf("invalid network with name %s", networkFlag) } diff --git a/pkg/flowcli/config/loader.go b/pkg/flowcli/config/loader.go index 07f30847b..3a1523999 100644 --- a/pkg/flowcli/config/loader.go +++ b/pkg/flowcli/config/loader.go @@ -28,7 +28,7 @@ import ( ) // ErrDoesNotExist is error to be returned when config file does not exists -var ErrDoesNotExist = errors.New("project config file does not exist") +var ErrDoesNotExist = errors.New("missing configuration, initialize it: flow init") // Exists checks if file exists on the specified path func Exists(path string) bool { @@ -140,7 +140,7 @@ func (l *Loader) Load(paths []string) (*Config, error) { // if no config was loaded - neither local nor global return an error if baseConf == nil { - return nil, fmt.Errorf("configuration not found, create one using `flow init`") + return nil, ErrDoesNotExist } baseConf, err := l.postprocess(baseConf) diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index 1635c71c1..472db5707 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -122,7 +122,7 @@ func (a *Accounts) Create( contracts []string, ) (*flow.Account, error) { if a.project == nil { - return nil, fmt.Errorf("missing configuration, initialize it: flow init") + return nil, config.ErrDoesNotExist } // if more than one key is provided and at least one weight is specified, make sure there isn't a missmatch @@ -225,7 +225,7 @@ func (a *Accounts) AddContract( updateExisting bool, ) (*flow.Account, error) { if a.project == nil { - return nil, fmt.Errorf("missing configuration, initialize it: flow init") + return nil, config.ErrDoesNotExist } account := a.project.AccountByName(accountName) diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 7062dfd6a..95094b583 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -101,7 +101,7 @@ func (p *Project) Init( func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, error) { if p.project == nil { - return nil, fmt.Errorf("missing configuration, initialize it: flow init") + return nil, config.ErrDoesNotExist } // check there are not multiple accounts with same contract diff --git a/pkg/flowcli/services/scripts.go b/pkg/flowcli/services/scripts.go index 1fece65e6..7bf636350 100644 --- a/pkg/flowcli/services/scripts.go +++ b/pkg/flowcli/services/scripts.go @@ -21,6 +21,8 @@ package services import ( "fmt" + "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/cadence" "github.com/onflow/flow-cli/pkg/flowcli" @@ -79,7 +81,7 @@ func (s *Scripts) execute(code []byte, args []string, argsJSON string, scriptPat if resolver.HasFileImports() { if s.project == nil { - return nil, fmt.Errorf("missing configuration, initialize it: flow init") + return nil, config.ErrDoesNotExist } if network == "" { return nil, fmt.Errorf("missing network, specify which network to use to resolve imports in script code") From c87872b0e58a6c9455d0f1046ce59de51998f3df Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 16:19:07 -0400 Subject: [PATCH 150/171] merge error --- pkg/flowcli/services/project.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 95094b583..75da6d4a3 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -91,7 +91,7 @@ func (p *Project) Init( proj.SetEmulatorServiceKey(serviceKey) } - err = proj.SaveDefault() + err = proj.Save(path) if err != nil { return nil, err } From f8e76a8845d5fffc4c07eb034d9856cce82e7e81 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 16:28:43 -0400 Subject: [PATCH 151/171] change example --- docs/deploy-project-contracts.md | 11 +++++------ docs/developer-updates/release-notes-v19.md | 11 +++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/deploy-project-contracts.md b/docs/deploy-project-contracts.md index d22afb616..28861226a 100644 --- a/docs/deploy-project-contracts.md +++ b/docs/deploy-project-contracts.md @@ -75,12 +75,11 @@ used during the deployment. Example: "testnet": { "my-testnet-account": [ "NonFungibleToken", { - "name": "KittyItems", - "args": [{ - "name": "supply", - "type": "UInt", - "value": "10", - }] + "name": "Foo", + "args": [ + { "name": "greeting", "type": "String", "value": "Hello World" }, + { "name": "supply", "type": "UInt32", "value": "10" } + ] }] } } diff --git a/docs/developer-updates/release-notes-v19.md b/docs/developer-updates/release-notes-v19.md index f324f3be7..f34c2b19e 100644 --- a/docs/developer-updates/release-notes-v19.md +++ b/docs/developer-updates/release-notes-v19.md @@ -15,12 +15,11 @@ the arguments in the configuration like so: "testnet": { "my-testnet-account": [ "NonFungibleToken", { - "name": "KittyItems", - "args": [{ - "name": "supply", - "type": "UInt", - "value": "10", - }] + "name": "Foo", + "args": [ + { "name": "greeting", "type": "String", "value": "Hello World" }, + { "name": "supply", "type": "UInt32", "value": "10" } + ] }] } } From 03d2b6065c4e04c7a08b4290e1fbabc5650fadd3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 17:30:06 -0400 Subject: [PATCH 152/171] refactor out the name from configuration --- pkg/flowcli/config/config.go | 8 +------- pkg/flowcli/config/json/deploy.go | 19 ++++++------------- pkg/flowcli/contracts/contracts.go | 8 ++++---- pkg/flowcli/contracts/preprocessor.go | 4 ++-- pkg/flowcli/project/project.go | 4 +++- pkg/flowcli/project/transaction.go | 16 ++++++---------- pkg/flowcli/services/accounts.go | 2 +- tests/Bar.cdc | 4 ++-- tests/flow.json | 4 ++-- 9 files changed, 27 insertions(+), 42 deletions(-) diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index e5c056435..8395fff3d 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -59,13 +59,7 @@ type Deploy struct { // ContractDeployment defines the deployment of the contract with possible args type ContractDeployment struct { Name string - Args []ContractArgument -} - -// ContractArgument defines contract init argument by name, type and value -type ContractArgument struct { - Name string - Arg cadence.Value + Args []cadence.Value } // Contract defines the configuration for a Cadence contract. diff --git a/pkg/flowcli/config/json/deploy.go b/pkg/flowcli/config/json/deploy.go index f1eb1dfab..3bb5e890b 100644 --- a/pkg/flowcli/config/json/deploy.go +++ b/pkg/flowcli/config/json/deploy.go @@ -22,6 +22,8 @@ import ( "encoding/json" "fmt" + "github.com/onflow/cadence" + jsoncdc "github.com/onflow/cadence/encoding/json" "github.com/onflow/flow-cli/pkg/flowcli/config" @@ -53,19 +55,11 @@ func (j jsonDeployments) transformToConfig() config.Deployments { }, ) } else { - args := make([]config.ContractArgument, 0) + args := make([]cadence.Value, 0) for _, arg := range contract.advanced.Args { - name := arg["name"] - delete(arg, "name") - - // todo check if parser exists for better solution b, _ := json.Marshal(arg) cadenceArg, _ := jsoncdc.Decode(b) - - args = append(args, config.ContractArgument{ - Name: name, - Arg: cadenceArg, - }) + args = append(args, cadenceArg) } contractDeploys = append( @@ -102,9 +96,8 @@ func transformDeploymentsToJSON(configDeployments config.Deployments) jsonDeploy args := make([]map[string]string, 0) for _, arg := range c.Args { args = append(args, map[string]string{ - "name": arg.Name, - "type": arg.Arg.Type().ID(), - "value": fmt.Sprintf("%v", arg.Arg.ToGoValue()), + "type": arg.Type().ID(), + "value": fmt.Sprintf("%v", arg.ToGoValue()), }) } diff --git a/pkg/flowcli/contracts/contracts.go b/pkg/flowcli/contracts/contracts.go index 79639b1c9..2b29f38b0 100644 --- a/pkg/flowcli/contracts/contracts.go +++ b/pkg/flowcli/contracts/contracts.go @@ -23,7 +23,7 @@ import ( "path" "strings" - "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/cadence" "github.com/onflow/cadence/runtime/ast" "github.com/onflow/cadence/runtime/common" @@ -40,7 +40,7 @@ type Contract struct { source string target flow.Address code string - args []config.ContractArgument + args []cadence.Value program *ast.Program dependencies map[string]*Contract aliases map[string]flow.Address @@ -52,7 +52,7 @@ func newContract( contractSource, contractCode string, target flow.Address, - args []config.ContractArgument, + args []cadence.Value, ) (*Contract, error) { program, err := parser2.ParseProgram(contractCode) if err != nil { @@ -84,7 +84,7 @@ func (c *Contract) Code() string { return c.code } -func (c *Contract) Args() []config.ContractArgument { +func (c *Contract) Args() []cadence.Value { return c.args } diff --git a/pkg/flowcli/contracts/preprocessor.go b/pkg/flowcli/contracts/preprocessor.go index baabae9c1..2278ff50f 100644 --- a/pkg/flowcli/contracts/preprocessor.go +++ b/pkg/flowcli/contracts/preprocessor.go @@ -21,7 +21,7 @@ package contracts import ( "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/cadence" "github.com/onflow/flow-go-sdk" ) @@ -46,7 +46,7 @@ func (p *Preprocessor) AddContractSource( contractName, contractSource string, target flow.Address, - args []config.ContractArgument, + args []cadence.Value, ) error { contractCode, err := p.loader.Load(contractSource) if err != nil { diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index b3d50f66c..c4f905e72 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -23,6 +23,8 @@ import ( "fmt" "path" + "github.com/onflow/cadence" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" @@ -46,7 +48,7 @@ type Contract struct { Name string Source string Target flow.Address - Args []config.ContractArgument + Args []cadence.Value } // Load loads a project configuration and returns the resulting project. diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index b9041517b..434fc0455 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -27,8 +27,6 @@ import ( jsoncdc "github.com/onflow/cadence/encoding/json" - "github.com/onflow/flow-cli/pkg/flowcli/config" - "github.com/onflow/flow-go-sdk/templates" "github.com/onflow/flow-cli/pkg/flowcli" @@ -92,7 +90,7 @@ func NewAddAccountContractTransaction( signer *Account, name string, source string, - args []config.ContractArgument, + args []cadence.Value, ) (*Transaction, error) { return addAccountContractWithArgs(signer, templates.Contract{ Name: name, @@ -111,10 +109,10 @@ func NewRemoveAccountContractTransaction(signer *Account, name string) (*Transac func addAccountContractWithArgs( signer *Account, contract templates.Contract, - args []config.ContractArgument, + args []cadence.Value, ) (*Transaction, error) { const addAccountContractTemplate = ` - transaction(name: String, code: String%s) { + transaction(name: String, code: String) { prepare(signer: AuthAccount) { signer.contracts.add(name: name, code: code.decodeHex()%s) } @@ -128,14 +126,12 @@ func addAccountContractWithArgs( AddRawArgument(jsoncdc.MustEncode(cadenceCode)). AddAuthorizer(signer.Address()) - txArgs, addArgs := "", "" + txArgs := "" for _, arg := range args { - tx.AddRawArgument(jsoncdc.MustEncode(arg.Arg)) - txArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Arg.Type().ID()) - addArgs += fmt.Sprintf(",%s: %s", arg.Name, arg.Name) + txArgs += fmt.Sprintf(",%s", arg) } - script := fmt.Sprintf(addAccountContractTemplate, txArgs, addArgs) + script := fmt.Sprintf(addAccountContractTemplate, txArgs) tx.SetScript([]byte(script)) t := &Transaction{tx: tx} diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index 472db5707..fe9b9f244 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -297,7 +297,7 @@ func (a *Accounts) addContract( account, contractName, string(contractSource), - []config.ContractArgument{}, // todo add support for args on account add-contract + []cadence.Value{}, // todo add support for args on account add-contract ) if err != nil { return nil, err diff --git a/tests/Bar.cdc b/tests/Bar.cdc index ab9158d4e..2869fc58e 100644 --- a/tests/Bar.cdc +++ b/tests/Bar.cdc @@ -1,7 +1,7 @@ import Foo from "./Foo.cdc" pub contract Bar { - init(a: String, b: UInt32) { - log(a.concat(b.toString())) + init(a: String, b: String) { + log(a.concat(b)) } } diff --git a/tests/flow.json b/tests/flow.json index 95c9e358c..5a90202e6 100644 --- a/tests/flow.json +++ b/tests/flow.json @@ -34,8 +34,8 @@ "NonFungibleToken", { "name": "Bar", "args": [ - { "name": "a", "type": "String", "value": "Hello World" }, - { "name": "b", "type": "UInt32", "value": "10" } + { "type": "String", "value": "Hello World" }, + { "type": "String", "value": "10" } ] } ] From bca6a4de2a47395118528ecfcd7c7d93c75ceb9f Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 17:53:52 -0400 Subject: [PATCH 153/171] bugfix types in deploy --- pkg/flowcli/project/transaction.go | 16 +++++++++++----- tests/Bar.cdc | 4 ++-- tests/flow.json | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index 434fc0455..e1a8616f9 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -112,9 +112,9 @@ func addAccountContractWithArgs( args []cadence.Value, ) (*Transaction, error) { const addAccountContractTemplate = ` - transaction(name: String, code: String) { + transaction(name: String, code: String %s) { prepare(signer: AuthAccount) { - signer.contracts.add(name: name, code: code.decodeHex()%s) + signer.contracts.add(name: name, code: code.decodeHex() %s) } }` @@ -126,12 +126,18 @@ func addAccountContractWithArgs( AddRawArgument(jsoncdc.MustEncode(cadenceCode)). AddAuthorizer(signer.Address()) - txArgs := "" for _, arg := range args { - txArgs += fmt.Sprintf(",%s", arg) + arg.Type().ID() + tx.AddRawArgument(jsoncdc.MustEncode(arg)) } - script := fmt.Sprintf(addAccountContractTemplate, txArgs) + txArgs, addArgs := "", "" + for i, arg := range args { + txArgs += fmt.Sprintf(",arg%d:%s", i, arg.Type().ID()) + addArgs += fmt.Sprintf(",arg%d", i) + } + + script := fmt.Sprintf(addAccountContractTemplate, txArgs, addArgs) tx.SetScript([]byte(script)) t := &Transaction{tx: tx} diff --git a/tests/Bar.cdc b/tests/Bar.cdc index 2869fc58e..ab9158d4e 100644 --- a/tests/Bar.cdc +++ b/tests/Bar.cdc @@ -1,7 +1,7 @@ import Foo from "./Foo.cdc" pub contract Bar { - init(a: String, b: String) { - log(a.concat(b)) + init(a: String, b: UInt32) { + log(a.concat(b.toString())) } } diff --git a/tests/flow.json b/tests/flow.json index 5a90202e6..42546d05d 100644 --- a/tests/flow.json +++ b/tests/flow.json @@ -35,7 +35,7 @@ "name": "Bar", "args": [ { "type": "String", "value": "Hello World" }, - { "type": "String", "value": "10" } + { "type": "UInt32", "value": "10" } ] } ] From a32d8a5351419aa99e5a91d697b9b87d2cbcf4d2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 17:59:44 -0400 Subject: [PATCH 154/171] remove valid args --- internal/accounts/accounts.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index 4eb9832c1..d15fdf1e2 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -21,6 +21,7 @@ package accounts import ( "bytes" "fmt" + "github.com/onflow/cadence" "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" @@ -31,7 +32,6 @@ var Cmd = &cobra.Command{ Use: "accounts", Short: "Utilities to manage accounts", TraverseChildren: true, - ValidArgs: []string{"get", "contract-add"}, } func init() { From 50025431d5fc95d7ea67a78376e1221ba3e547fe Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Wed, 28 Apr 2021 18:04:05 -0400 Subject: [PATCH 155/171] add bugfix to release notes --- docs/developer-updates/release-notes-v19.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/developer-updates/release-notes-v19.md b/docs/developer-updates/release-notes-v19.md index f34c2b19e..4c52d0e22 100644 --- a/docs/developer-updates/release-notes-v19.md +++ b/docs/developer-updates/release-notes-v19.md @@ -101,4 +101,8 @@ different keys. This new functionality is backward compatible. ### Keys Generate JSON output Keys generation output in JSON format was fixed and it now shows correctly -private and public keys. \ No newline at end of file +private and public keys. + +### Account Key Index When Sending Transactions +Account key index is now fetched from the configuration and +it doesn't default to 0 anymore. \ No newline at end of file From ac066140fe560cbcfbc9f8362b28c4d058be3584 Mon Sep 17 00:00:00 2001 From: Greg <75445744+sideninja@users.noreply.github.com> Date: Wed, 28 Apr 2021 18:45:23 -0400 Subject: [PATCH 156/171] Revert "Remove multiple keys" --- internal/command/command.go | 2 +- internal/emulator/start.go | 19 +- pkg/flowcli/config/config.go | 2 +- pkg/flowcli/config/config_test.go | 12 +- pkg/flowcli/config/json/account.go | 149 +++++--------- pkg/flowcli/config/json/account_test.go | 250 +++++++++++++----------- pkg/flowcli/config/json/config_test.go | 4 +- pkg/flowcli/config/loader_test.go | 36 ++-- pkg/flowcli/project/account.go | 50 +++-- pkg/flowcli/project/keys.go | 18 +- pkg/flowcli/project/project.go | 6 +- pkg/flowcli/project/project_test.go | 36 ++-- pkg/flowcli/project/transaction.go | 6 +- 13 files changed, 286 insertions(+), 304 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index 4a8cc8a87..b8ff3b547 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -225,7 +225,7 @@ func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (st return hostFlag, nil } // network flag with project initialized is next - if proj != nil { + if networkFlag != "" && proj != nil { check := proj.NetworkByName(networkFlag) if check == nil { return "", fmt.Errorf("network with name %s does not exist in configuration", networkFlag) diff --git a/internal/emulator/start.go b/internal/emulator/start.go index cdbd789fe..803900bcb 100644 --- a/internal/emulator/start.go +++ b/internal/emulator/start.go @@ -77,22 +77,23 @@ func ConfiguredServiceKey( } } - serviceAccount, err := proj.EmulatorServiceAccount() - if err != nil { - util.Exit(1, err.Error()) - } + serviceAccount, _ := proj.EmulatorServiceAccount() - privateKey, err := serviceAccount.Key().PrivateKey() - if err != nil { + serviceKeyHex, ok := serviceAccount.DefaultKey().(*project.HexAccountKey) + if !ok { util.Exit(1, "Only hexadecimal keys can be used as the emulator service account key.") } - err = serviceAccount.Key().Validate() + privateKey, err := crypto.DecodePrivateKeyHex(serviceKeyHex.SigAlgo(), serviceKeyHex.PrivateKeyHex()) if err != nil { - util.Exit(1, err.Error()) + util.Exitf( + 1, + "Invalid private key in \"%s\" emulator configuration", + config.DefaultEmulatorConfigName, + ) } - return *privateKey, serviceAccount.Key().SigAlgo(), serviceAccount.Key().HashAlgo() + return privateKey, serviceKeyHex.SigAlgo(), serviceKeyHex.HashAlgo() } func init() { diff --git a/pkg/flowcli/config/config.go b/pkg/flowcli/config/config.go index 8395fff3d..b9db7e2a1 100644 --- a/pkg/flowcli/config/config.go +++ b/pkg/flowcli/config/config.go @@ -74,7 +74,7 @@ type Contract struct { type Account struct { Name string Address flow.Address - Key AccountKey + Keys []AccountKey } // AccountKey defines the configuration for a Flow account key. diff --git a/pkg/flowcli/config/config_test.go b/pkg/flowcli/config/config_test.go index 81db20039..0b906e0dc 100644 --- a/pkg/flowcli/config/config_test.go +++ b/pkg/flowcli/config/config_test.go @@ -86,7 +86,7 @@ func generateComplexConfig() config.Config { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -94,11 +94,11 @@ func generateComplexConfig() config.Config { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }, { Name: "account-2", Address: flow.HexToAddress("2c1162386b0a245f"), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -106,11 +106,11 @@ func generateComplexConfig() config.Config { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }, { Name: "account-4", Address: flow.HexToAddress("f8d6e0586b0a20c1"), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -118,7 +118,7 @@ func generateComplexConfig() config.Config { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }}, Networks: config.Networks{{ Name: "emulator", diff --git a/pkg/flowcli/config/json/account.go b/pkg/flowcli/config/json/account.go index 9fc936059..02b66205c 100644 --- a/pkg/flowcli/config/json/account.go +++ b/pkg/flowcli/config/json/account.go @@ -50,27 +50,33 @@ func (j jsonAccounts) transformToConfig() config.Accounts { account = config.Account{ Name: accountName, Address: transformAddress(a.Simple.Address), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, HashAlgo: crypto.SHA3_256, Context: map[string]string{ - config.PrivateKeyField: a.Simple.Key, + config.PrivateKeyField: a.Simple.Keys, }, - }, + }}, } } else { // advanced format + keys := make([]config.AccountKey, 0) + for _, key := range a.Advanced.Keys { + key := config.AccountKey{ + Type: key.Type, + Index: key.Index, + SigAlgo: crypto.StringToSignatureAlgorithm(key.SigAlgo), + HashAlgo: crypto.StringToHashAlgorithm(key.HashAlgo), + Context: key.Context, + } + keys = append(keys, key) + } + account = config.Account{ Name: accountName, Address: transformAddress(a.Advanced.Address), - Key: config.AccountKey{ - Type: a.Advanced.Key.Type, - Index: a.Advanced.Key.Index, - SigAlgo: crypto.StringToSignatureAlgorithm(a.Advanced.Key.SigAlgo), - HashAlgo: crypto.StringToHashAlgorithm(a.Advanced.Key.HashAlgo), - Context: a.Advanced.Key.Context, - }, + Keys: keys, } } @@ -80,33 +86,39 @@ func (j jsonAccounts) transformToConfig() config.Accounts { return accounts } -func isDefaultKeyFormat(key config.AccountKey) bool { - return key.Index == 0 && - key.Type == config.KeyTypeHex && - key.SigAlgo == crypto.ECDSA_P256 && - key.HashAlgo == crypto.SHA3_256 +func isDefaultKeyFormat(keys []config.AccountKey) bool { + return len(keys) == 1 && keys[0].Index == 0 && + keys[0].Type == config.KeyTypeHex && + keys[0].SigAlgo == crypto.ECDSA_P256 && + keys[0].HashAlgo == crypto.SHA3_256 } func transformSimpleAccountToJSON(a config.Account) jsonAccount { return jsonAccount{ Simple: jsonAccountSimple{ Address: a.Address.String(), - Key: a.Key.Context[config.PrivateKeyField], + Keys: a.Keys[0].Context[config.PrivateKeyField], }, } } func transformAdvancedAccountToJSON(a config.Account) jsonAccount { + var keys []jsonAccountKey + + for _, k := range a.Keys { + keys = append(keys, jsonAccountKey{ + Type: k.Type, + Index: k.Index, + SigAlgo: k.SigAlgo.String(), + HashAlgo: k.HashAlgo.String(), + Context: k.Context, + }) + } + return jsonAccount{ Advanced: jsonAccountAdvanced{ Address: a.Address.String(), - Key: jsonAccountKey{ - Type: a.Key.Type, - Index: a.Key.Index, - SigAlgo: a.Key.SigAlgo.String(), - HashAlgo: a.Key.HashAlgo.String(), - Context: a.Key.Context, - }, + Keys: keys, }, } } @@ -117,7 +129,7 @@ func transformAccountsToJSON(accounts config.Accounts) jsonAccounts { for _, a := range accounts { // if simple - if isDefaultKeyFormat(a.Key) { + if isDefaultKeyFormat(a.Keys) { jsonAccounts[a.Name] = transformSimpleAccountToJSON(a) } else { // if advanced jsonAccounts[a.Name] = transformAdvancedAccountToJSON(a) @@ -129,12 +141,12 @@ func transformAccountsToJSON(accounts config.Accounts) jsonAccounts { type jsonAccountSimple struct { Address string `json:"address"` - Key string `json:"key"` + Keys string `json:"keys"` } type jsonAccountAdvanced struct { - Address string `json:"address"` - Key jsonAccountKey `json:"key"` + Address string `json:"address"` + Keys []jsonAccountKey `json:"keys"` } type jsonAccountKey struct { @@ -145,89 +157,30 @@ type jsonAccountKey struct { Context map[string]string `json:"context"` } -type jsonAccountSimpleOld struct { - Address string `json:"address"` - Keys string `json:"keys"` -} - -type jsonAccountAdvancedOld struct { - Address string `json:"address"` - Keys []jsonAccountKey `json:"keys"` -} - type jsonAccount struct { Simple jsonAccountSimple Advanced jsonAccountAdvanced } -type FormatType int - -const ( - simpleFormat FormatType = 0 - advancedFormat FormatType = 1 - simpleOldFormat FormatType = 2 - advancedOldFormat FormatType = 3 -) - -func decideFormat(b []byte) (FormatType, error) { - var raw map[string]interface{} - err := json.Unmarshal(b, &raw) - if err != nil { - return 0, err - } - - if raw["keys"] != nil { - switch raw["keys"].(type) { - case string: - return simpleOldFormat, nil - default: - return advancedOldFormat, nil - } - } - - switch raw["key"].(type) { - case string: - return simpleFormat, nil - default: - return advancedFormat, nil - } -} - func (j *jsonAccount) UnmarshalJSON(b []byte) error { - format, err := decideFormat(b) - if err != nil { - return err - } - - switch format { - case simpleFormat: - var simple jsonAccountSimple - err = json.Unmarshal(b, &simple) + // try simple format + var simple jsonAccountSimple + err := json.Unmarshal(b, &simple) + if err == nil { j.Simple = simple + return nil + } - case advancedFormat: - var advanced jsonAccountAdvanced - err = json.Unmarshal(b, &advanced) + // try advanced format + var advanced jsonAccountAdvanced + err = json.Unmarshal(b, &advanced) + if err == nil { j.Advanced = advanced - - case simpleOldFormat: - var simpleOld jsonAccountSimpleOld - err = json.Unmarshal(b, &simpleOld) - j.Simple = jsonAccountSimple{ - Address: simpleOld.Address, - Key: simpleOld.Keys, - } - - case advancedOldFormat: - var advancedOld jsonAccountAdvancedOld - err = json.Unmarshal(b, &advancedOld) - j.Advanced = jsonAccountAdvanced{ - Address: advancedOld.Address, - Key: advancedOld.Keys[0], - } + return nil } + // TODO: better error handling - here we just return error from advanced case return err } diff --git a/pkg/flowcli/config/json/account_test.go b/pkg/flowcli/config/json/account_test.go index f9b5120ac..3bbba9805 100644 --- a/pkg/flowcli/config/json/account_test.go +++ b/pkg/flowcli/config/json/account_test.go @@ -28,7 +28,7 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { b := []byte(`{ "test": { "address": "service", - "key": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -39,25 +39,28 @@ func Test_ConfigAccountKeysSimple(t *testing.T) { accounts := jsonAccounts.transformToConfig() assert.Equal(t, accounts.GetByName("test").Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, accounts.GetByName("test").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("test").Key.Index, 0) - assert.Equal(t, accounts.GetByName("test").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("test").Key.Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("test").Keys, 1) + assert.Equal(t, accounts.GetByName("test").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("test").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("test").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("test").Keys[0].Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigAccountKeysAdvanced(t *testing.T) { b := []byte(`{ "test": { "address": "service", - "key": { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": [ + { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } } - } + ] } }`) @@ -69,21 +72,70 @@ func Test_ConfigAccountKeysAdvanced(t *testing.T) { account := accounts.GetByName("test") assert.Equal(t, account.Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, account.Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, account.Key.Index, 0) - assert.Equal(t, account.Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, account.Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, account.Keys, 1) + assert.Equal(t, account.Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, account.Keys[0].Index, 0) + assert.Equal(t, account.Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, account.Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") +} + +func Test_ConfigAccountKeysAdvancedMultiple(t *testing.T) { + b := []byte(`{ + "test": { + "address": "service", + "keys": [ + { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } + }, + { + "type": "hex", + "index": 1, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "2372967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } + } + ] + } + }`) + + var jsonAccounts jsonAccounts + err := json.Unmarshal(b, &jsonAccounts) + assert.NoError(t, err) + + accounts := jsonAccounts.transformToConfig() + account := accounts.GetByName("test") + + assert.Equal(t, account.Address.String(), "f8d6e0586b0a20c7") + assert.Len(t, account.Keys, 2) + + assert.Equal(t, account.Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, account.Keys[0].Index, 0) + assert.Equal(t, account.Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, account.Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + + assert.Equal(t, account.Keys[1].HashAlgo.String(), "SHA3_256") + assert.Equal(t, account.Keys[1].Index, 1) + assert.Equal(t, account.Keys[1].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, account.Keys[1].Context["privateKey"], "2372967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigMultipleAccountsSimple(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service-1", - "key": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" }, "testnet-account": { "address": "0x2c1162386b0a245f", - "key": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -95,43 +147,49 @@ func Test_ConfigMultipleAccountsSimple(t *testing.T) { assert.Equal(t, accounts.GetByName("emulator-account").Name, "emulator-account") assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "0000000000000000") - assert.Equal(t, accounts.GetByName("emulator-account").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("emulator-account").Key.Index, 0) - assert.Equal(t, accounts.GetByName("emulator-account").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("emulator-account").Key.Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "2c1162386b0a245f") - assert.Equal(t, accounts.GetByName("testnet-account").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("testnet-account").Key.Index, 0) - assert.Equal(t, accounts.GetByName("testnet-account").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("testnet-account").Key.Context["privateKey"], "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Context["privateKey"], "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service", - "key": { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": [ + { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } } - } + ] }, "testnet-account": { "address": "1c1162386b0a245f", - "key": { - "type": "0x18d6e0586b0a20c7", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": [ + { + "type": "0x18d6e0586b0a20c7", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } } - } + ] } }`) @@ -142,35 +200,39 @@ func Test_ConfigMultipleAccountsAdvanced(t *testing.T) { accounts := jsonAccounts.transformToConfig() assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, accounts.GetByName("emulator-account").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("emulator-account").Key.Index, 0) - assert.Equal(t, accounts.GetByName("emulator-account").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("emulator-account").Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "1c1162386b0a245f") - assert.Equal(t, accounts.GetByName("testnet-account").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("testnet-account").Key.Index, 0) - assert.Equal(t, accounts.GetByName("testnet-account").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("testnet-account").Key.Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigMixedAccounts(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service", - "key": { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": [ + { + "type": "hex", + "index": 0, + "signatureAlgorithm": "ECDSA_P256", + "hashAlgorithm": "SHA3_256", + "context": { + "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + } } - } + ] }, "testnet-account": { "address": "3c1162386b0a245f", - "key": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -181,27 +243,29 @@ func Test_ConfigMixedAccounts(t *testing.T) { accounts := jsonAccounts.transformToConfig() assert.Equal(t, accounts.GetByName("emulator-account").Address.String(), "f8d6e0586b0a20c7") - assert.Equal(t, accounts.GetByName("emulator-account").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("emulator-account").Key.Index, 0) - assert.Equal(t, accounts.GetByName("emulator-account").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("emulator-account").Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("emulator-account").Keys, 1) + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, accounts.GetByName("testnet-account").Address.String(), "3c1162386b0a245f") - assert.Equal(t, accounts.GetByName("testnet-account").Key.HashAlgo.String(), "SHA3_256") - assert.Equal(t, accounts.GetByName("testnet-account").Key.Index, 0) - assert.Equal(t, accounts.GetByName("testnet-account").Key.SigAlgo.String(), "ECDSA_P256") - assert.Equal(t, accounts.GetByName("testnet-account").Key.Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Len(t, accounts.GetByName("testnet-account").Keys, 1) + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].HashAlgo.String(), "SHA3_256") + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Index, 0) + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].SigAlgo.String(), "ECDSA_P256") + assert.Equal(t, accounts.GetByName("testnet-account").Keys[0].Context["privateKey"], "2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_ConfigAccountsMap(t *testing.T) { b := []byte(`{ "emulator-account": { "address": "service-1", - "key": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" }, "testnet-account": { "address": "3c1162386b0a245f", - "key": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" + "keys": "1232967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" } }`) @@ -216,7 +280,7 @@ func Test_ConfigAccountsMap(t *testing.T) { } func Test_TransformDefaultAccountToJSON(t *testing.T) { - b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","key":{"type":"hex","index":0,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}},"testnet-account":{"address":"3c1162386b0a245f","key":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}`) + b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","keys":[{"type":"hex","index":0,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}`) var jsonAccounts jsonAccounts err := json.Unmarshal(b, &jsonAccounts) @@ -232,7 +296,7 @@ func Test_TransformDefaultAccountToJSON(t *testing.T) { } func Test_TransformAccountToJSON(t *testing.T) { - b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","key":{"type":"hex","index":1,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}},"testnet-account":{"address":"3c1162386b0a245f","key":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}`) + b := []byte(`{"emulator-account":{"address":"f8d6e0586b0a20c7","keys":[{"type":"hex","index":1,"signatureAlgorithm":"ECDSA_P256","hashAlgorithm":"SHA3_256","context":{"privateKey":"1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}]},"testnet-account":{"address":"3c1162386b0a245f","keys":"2272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47"}}`) var jsonAccounts jsonAccounts err := json.Unmarshal(b, &jsonAccounts) @@ -245,45 +309,3 @@ func Test_TransformAccountToJSON(t *testing.T) { assert.Equal(t, string(b), string(x)) } - -func Test_SupportForOldFormatWithMultipleKeys(t *testing.T) { - b := []byte(`{ - "emulator-account": { - "address": "service-1", - "chain": "flow-emulator", - "keys": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - }, - "testnet-account": { - "address": "3c1162386b0a245f", - "chain": "testnet", - "keys": [ - { - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47" - } - },{ - "type": "hex", - "index": 0, - "signatureAlgorithm": "ECDSA_P256", - "hashAlgorithm": "SHA3_256", - "context": { - "privateKey": "2332967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b44" - } - } - ] - } - }`) - - var jsonAccounts jsonAccounts - err := json.Unmarshal(b, &jsonAccounts) - assert.NoError(t, err) - - conf := jsonAccounts.transformToConfig() - - assert.Equal(t, conf.GetByName("testnet-account").Key.Context["privateKey"], "1272967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") - assert.Equal(t, conf.GetByName("emulator-account").Key.Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") -} diff --git a/pkg/flowcli/config/json/config_test.go b/pkg/flowcli/config/json/config_test.go index d3be5379d..04f88f914 100644 --- a/pkg/flowcli/config/json/config_test.go +++ b/pkg/flowcli/config/json/config_test.go @@ -38,7 +38,7 @@ func Test_SimpleJSONConfig(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "key": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys": "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } }, "deploys": {} @@ -50,6 +50,6 @@ func Test_SimpleJSONConfig(t *testing.T) { assert.NoError(t, err) assert.Equal(t, 1, len(conf.Accounts)) assert.Equal(t, "emulator-account", conf.Accounts[0].Name) - assert.Equal(t, "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Key.Context["privateKey"]) + assert.Equal(t, "11c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Keys[0].Context["privateKey"]) assert.Equal(t, "127.0.0.1:3569", conf.Networks.GetByName("emulator").Host) } diff --git a/pkg/flowcli/config/loader_test.go b/pkg/flowcli/config/loader_test.go index 58f70ffb3..024ed3606 100644 --- a/pkg/flowcli/config/loader_test.go +++ b/pkg/flowcli/config/loader_test.go @@ -43,7 +43,7 @@ func Test_JSONSimple(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } }, "deployments": {} @@ -60,7 +60,7 @@ func Test_JSONSimple(t *testing.T) { assert.NoError(t, loadErr) assert.Equal(t, 1, len(conf.Accounts)) - assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Key.Context["privateKey"]) + assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Keys[0].Context["privateKey"]) } func Test_ComposeJSON(t *testing.T) { @@ -68,7 +68,7 @@ func Test_ComposeJSON(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -77,7 +77,7 @@ func Test_ComposeJSON(t *testing.T) { "accounts":{ "admin-account":{ "address":"f1d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -97,11 +97,11 @@ func Test_ComposeJSON(t *testing.T) { assert.NoError(t, loadErr) assert.Equal(t, 2, len(conf.Accounts)) assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - conf.Accounts.GetByName("emulator-account").Key.Context["privateKey"], + conf.Accounts.GetByName("emulator-account").Keys[0].Context["privateKey"], ) assert.NotNil(t, conf.Accounts.GetByName("admin-account")) assert.Equal(t, "3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - conf.Accounts.GetByName("admin-account").Key.Context["privateKey"], + conf.Accounts.GetByName("admin-account").Keys[0].Context["privateKey"], ) } @@ -110,7 +110,7 @@ func Test_ComposeJSONOverwrite(t *testing.T) { "accounts": { "admin-account": { "address": "f8d6e0586b0a20c7", - "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -119,7 +119,7 @@ func Test_ComposeJSONOverwrite(t *testing.T) { "accounts":{ "admin-account":{ "address":"f1d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -140,7 +140,7 @@ func Test_ComposeJSONOverwrite(t *testing.T) { assert.Equal(t, 1, len(conf.Accounts)) assert.NotNil(t, conf.Accounts.GetByName("admin-account")) assert.Equal(t, "3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", - conf.Accounts.GetByName("admin-account").Key.Context["privateKey"], + conf.Accounts.GetByName("admin-account").Keys[0].Context["privateKey"], ) } @@ -149,7 +149,7 @@ func Test_FromFileAccountSimple(t *testing.T) { "accounts": { "service-account": { "address": "f8d6e0586b0a20c7", - "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account": { "fromFile": "private.json" } } @@ -159,7 +159,7 @@ func Test_FromFileAccountSimple(t *testing.T) { "accounts":{ "admin-account":{ "address":"f1d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -188,7 +188,7 @@ func Test_FromFileAccountComplex(t *testing.T) { "accounts": { "service-account": { "address": "f8d6e0586b0a20c7", - "key": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys": "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account-1": { "fromFile": "private.json" }, "admin-account-3": { "fromFile": "private.json" }, @@ -200,15 +200,15 @@ func Test_FromFileAccountComplex(t *testing.T) { "accounts":{ "admin-account-1":{ "address":"f1d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account-2":{ "address":"f2d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" }, "admin-account-3":{ "address":"f3d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -217,7 +217,7 @@ func Test_FromFileAccountComplex(t *testing.T) { "accounts":{ "admin-account-5":{ "address":"f5d6e0586b0a20c7", - "key":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" + "keys":"3335dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7" } } }`) @@ -253,7 +253,7 @@ func Test_JSONEnv(t *testing.T) { "accounts": { "emulator-account": { "address": "f8d6e0586b0a20c7", - "key": "$EMULATOR_KEY" + "keys": "$EMULATOR_KEY" } } }`) @@ -271,5 +271,5 @@ func Test_JSONEnv(t *testing.T) { assert.NoError(t, loadErr) assert.Equal(t, 1, len(conf.Accounts)) - assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Key.Context["privateKey"]) + assert.Equal(t, "21c5dfdeb0ff03a7a73ef39788563b62c89adea67bbb21ab95e5f710bd1d40b7", conf.Accounts[0].Keys[0].Context["privateKey"]) } diff --git a/pkg/flowcli/project/account.go b/pkg/flowcli/project/account.go index 5270342b2..85245f191 100644 --- a/pkg/flowcli/project/account.go +++ b/pkg/flowcli/project/account.go @@ -31,7 +31,7 @@ import ( type Account struct { name string address flow.Address - key AccountKey + keys []AccountKey } func (a *Account) Address() flow.Address { @@ -42,12 +42,16 @@ func (a *Account) Name() string { return a.name } -func (a *Account) Key() AccountKey { - return a.key +func (a *Account) Keys() []AccountKey { + return a.keys } -func (a *Account) SetKey(key AccountKey) { - a.key = key +func (a *Account) DefaultKey() AccountKey { + return a.keys[0] +} + +func (a *Account) SetDefaultKey(key AccountKey) { + a.keys[0] = key } func accountsFromConfig(conf *config.Config) ([]*Account, error) { @@ -69,20 +73,26 @@ func AccountFromAddressAndKey(address flow.Address, privateKey crypto.PrivateKey return &Account{ name: "", address: address, - key: NewHexAccountKeyFromPrivateKey(0, crypto.SHA3_256, privateKey), + keys: []AccountKey{key}, } } -func AccountFromConfig(account config.Account) (*Account, error) { - key, err := NewAccountKey(account.Key) - if err != nil { - return nil, err +func AccountFromConfig(accountConf config.Account) (*Account, error) { + accountKeys := make([]AccountKey, 0, len(accountConf.Keys)) + + for _, key := range accountConf.Keys { + accountKey, err := NewAccountKey(key) + if err != nil { + return nil, err + } + + accountKeys = append(accountKeys, accountKey) } return &Account{ - name: account.Name, - address: account.Address, - key: key, + name: accountConf.Name, + address: accountConf.Address, + keys: accountKeys, }, nil } @@ -97,10 +107,16 @@ func accountsToConfig(accounts []*Account) config.Accounts { } func accountToConfig(account *Account) config.Account { + keyConfigs := make([]config.AccountKey, 0, len(account.keys)) + + for _, key := range account.keys { + keyConfigs = append(keyConfigs, key.ToConfig()) + } + return config.Account{ Name: account.name, Address: account.address, - Key: account.key.ToConfig(), + Keys: keyConfigs, } } @@ -115,9 +131,13 @@ func generateEmulatorServiceAccount(sigAlgo crypto.SignatureAlgorithm, hashAlgo return nil, fmt.Errorf("failed to generate emulator service key: %v", err) } + serviceAccountKey := NewHexAccountKeyFromPrivateKey(0, hashAlgo, privateKey) + return &Account{ name: config.DefaultEmulatorServiceAccountName, address: flow.ServiceAddress(flow.Emulator), - key: NewHexAccountKeyFromPrivateKey(0, hashAlgo, privateKey), + keys: []AccountKey{ + serviceAccountKey, + }, }, nil } diff --git a/pkg/flowcli/project/keys.go b/pkg/flowcli/project/keys.go index 3a161d885..313bd101b 100644 --- a/pkg/flowcli/project/keys.go +++ b/pkg/flowcli/project/keys.go @@ -40,7 +40,6 @@ type AccountKey interface { Signer(ctx context.Context) (crypto.Signer, error) ToConfig() config.AccountKey Validate() error - PrivateKey() (*crypto.PrivateKey, error) } func NewAccountKey(accountKeyConf config.AccountKey) (AccountKey, error) { @@ -130,10 +129,6 @@ func (a *KmsAccountKey) Validate() error { return util.GcloudApplicationSignin(resourceID) } -func (a *KmsAccountKey) PrivateKey() (*crypto.PrivateKey, error) { - return nil, fmt.Errorf("private key not accessible") -} - func newKmsAccountKey(key config.AccountKey) (AccountKey, error) { accountKMSKey, err := cloudkms.KeyFromResourceID(key.Context[config.KMSContextField]) if err != nil { @@ -193,8 +188,8 @@ func (a *HexAccountKey) Signer(ctx context.Context) (crypto.Signer, error) { return crypto.NewInMemorySigner(a.privateKey, a.HashAlgo()), nil } -func (a *HexAccountKey) PrivateKey() (*crypto.PrivateKey, error) { - return &a.privateKey, nil +func (a *HexAccountKey) PrivateKey() crypto.PrivateKey { + return a.privateKey } func (a *HexAccountKey) ToConfig() config.AccountKey { @@ -209,15 +204,6 @@ func (a *HexAccountKey) ToConfig() config.AccountKey { } } -func (a *HexAccountKey) Validate() error { - _, err := crypto.DecodePrivateKeyHex(a.sigAlgo, a.PrivateKeyHex()) - if err != nil { - return fmt.Errorf("invalid private key") - } - - return nil -} - func (a *HexAccountKey) PrivateKeyHex() string { return hex.EncodeToString(a.privateKey.Encode()) } diff --git a/pkg/flowcli/project/project.go b/pkg/flowcli/project/project.go index c4f905e72..e153974f7 100644 --- a/pkg/flowcli/project/project.go +++ b/pkg/flowcli/project/project.go @@ -172,10 +172,10 @@ func (p *Project) EmulatorServiceAccount() (*Account, error) { // SetEmulatorServiceKey sets the default emulator service account private key. func (p *Project) SetEmulatorServiceKey(privateKey crypto.PrivateKey) { acc := p.AccountByName(config.DefaultEmulatorServiceAccountName) - acc.SetKey( + acc.SetDefaultKey( NewHexAccountKeyFromPrivateKey( - acc.Key().Index(), - acc.Key().HashAlgo(), + acc.DefaultKey().Index(), + acc.DefaultKey().HashAlgo(), privateKey, ), ) diff --git a/pkg/flowcli/project/project_test.go b/pkg/flowcli/project/project_test.go index 91dcf1e12..8ba3569e3 100644 --- a/pkg/flowcli/project/project_test.go +++ b/pkg/flowcli/project/project_test.go @@ -96,7 +96,7 @@ func generateComplexProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -104,11 +104,11 @@ func generateComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }, { Name: "account-2", Address: flow.HexToAddress("2c1162386b0a245f"), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -116,11 +116,11 @@ func generateComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }, { Name: "account-4", Address: flow.HexToAddress("f8d6e0586b0a20c1"), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -128,7 +128,7 @@ func generateComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }}, Networks: config.Networks{{ Name: "emulator", @@ -166,7 +166,7 @@ func generateSimpleProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -174,7 +174,7 @@ func generateSimpleProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }}, Networks: config.Networks{{ Name: "emulator", @@ -217,7 +217,7 @@ func generateAliasesProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -225,7 +225,7 @@ func generateAliasesProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }}, Networks: config.Networks{{ Name: "emulator", @@ -284,7 +284,7 @@ func generateAliasesComplexProject() Project { Accounts: config.Accounts{{ Name: "emulator-account", Address: flow.ServiceAddress(flow.Emulator), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -292,11 +292,11 @@ func generateAliasesComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }, { Name: "testnet-account", Address: flow.HexToAddress("1e82856bf20e2aa6"), - Key: config.AccountKey{ + Keys: []config.AccountKey{{ Type: config.KeyTypeHex, Index: 0, SigAlgo: crypto.ECDSA_P256, @@ -304,7 +304,7 @@ func generateAliasesComplexProject() Project { Context: map[string]string{ "privateKey": "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47", }, - }, + }}, }}, Networks: config.Networks{{ Name: "emulator", @@ -342,7 +342,7 @@ func Test_EmulatorConfigSimple(t *testing.T) { emulatorServiceAccount, _ := p.EmulatorServiceAccount() assert.Equal(t, emulatorServiceAccount.name, "emulator-account") - assert.Equal(t, emulatorServiceAccount.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, emulatorServiceAccount.keys[0].ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, flow.ServiceAddress("flow-emulator").String(), emulatorServiceAccount.Address().String()) } @@ -358,7 +358,7 @@ func Test_AccountByNameSimple(t *testing.T) { acc := p.AccountByName("emulator-account") assert.Equal(t, flow.ServiceAddress("flow-emulator").String(), acc.Address().String()) - assert.Equal(t, acc.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, acc.DefaultKey().ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_HostSimple(t *testing.T) { @@ -421,7 +421,7 @@ func Test_EmulatorConfigComplex(t *testing.T) { emulatorServiceAccount, _ := p.EmulatorServiceAccount() assert.Equal(t, emulatorServiceAccount.name, "emulator-account") - assert.Equal(t, emulatorServiceAccount.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, emulatorServiceAccount.keys[0].ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") assert.Equal(t, emulatorServiceAccount.Address().String(), flow.ServiceAddress("flow-emulator").String()) } @@ -439,7 +439,7 @@ func Test_AccountByNameComplex(t *testing.T) { acc := p.AccountByName("account-2") assert.Equal(t, acc.Address().String(), "2c1162386b0a245f") - assert.Equal(t, acc.key.ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") + assert.Equal(t, acc.DefaultKey().ToConfig().Context["privateKey"], "dd72967fd2bd75234ae9037dd4694c1f00baad63a10c35172bf65fbb8ad74b47") } func Test_HostComplex(t *testing.T) { diff --git a/pkg/flowcli/project/transaction.go b/pkg/flowcli/project/transaction.go index e1a8616f9..fb0c036bf 100644 --- a/pkg/flowcli/project/transaction.go +++ b/pkg/flowcli/project/transaction.go @@ -222,7 +222,7 @@ func (t *Transaction) SetScriptWithArgs(script []byte, args []string, argsJSON s // SetSigner sets the signer for transaction func (t *Transaction) SetSigner(account *Account) error { - err := account.Key().Validate() + err := account.DefaultKey().Validate() if err != nil { return err } @@ -301,8 +301,8 @@ func (t *Transaction) AddAuthorizers(authorizers []flow.Address) *Transaction { // Sign signs transaction using signer account func (t *Transaction) Sign() (*Transaction, error) { - keyIndex := t.signer.Key().Index() - signer, err := t.signer.Key().Signer(context.Background()) + keyIndex := t.signer.DefaultKey().Index() + signer, err := t.signer.DefaultKey().Signer(context.Background()) if err != nil { return nil, err } From 12ef909fdd3ade774efd4191c3008a1f6b57744a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 07:37:39 -0400 Subject: [PATCH 157/171] fix from revert keys --- internal/command/command.go | 2 +- pkg/flowcli/config/parsers.go | 6 +++--- pkg/flowcli/project/account.go | 4 +++- pkg/flowcli/services/accounts.go | 2 +- pkg/flowcli/services/project.go | 2 +- pkg/flowcli/services/transactions.go | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/internal/command/command.go b/internal/command/command.go index b8ff3b547..4a8cc8a87 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -225,7 +225,7 @@ func resolveHost(proj *project.Project, hostFlag string, networkFlag string) (st return hostFlag, nil } // network flag with project initialized is next - if networkFlag != "" && proj != nil { + if proj != nil { check := proj.NetworkByName(networkFlag) if check == nil { return "", fmt.Errorf("network with name %s does not exist in configuration", networkFlag) diff --git a/pkg/flowcli/config/parsers.go b/pkg/flowcli/config/parsers.go index 62e815190..e7aaaad25 100644 --- a/pkg/flowcli/config/parsers.go +++ b/pkg/flowcli/config/parsers.go @@ -34,7 +34,7 @@ func StringToAccount( return nil, err } - accountKey := AccountKey{ + accountKey := []AccountKey{{ Type: KeyTypeHex, Index: parsedIndex, SigAlgo: crypto.StringToSignatureAlgorithm(sigAlgo), @@ -42,12 +42,12 @@ func StringToAccount( Context: map[string]string{ PrivateKeyField: strings.ReplaceAll(parsedKey.String(), "0x", ""), }, - } + }} return &Account{ Name: name, Address: *parsedAddress, - Key: accountKey, + Keys: accountKey, }, nil } diff --git a/pkg/flowcli/project/account.go b/pkg/flowcli/project/account.go index 85245f191..3090f65c7 100644 --- a/pkg/flowcli/project/account.go +++ b/pkg/flowcli/project/account.go @@ -73,7 +73,9 @@ func AccountFromAddressAndKey(address flow.Address, privateKey crypto.PrivateKey return &Account{ name: "", address: address, - keys: []AccountKey{key}, + keys: []AccountKey{ + NewHexAccountKeyFromPrivateKey(0, crypto.SHA3_256, privateKey), + }, } } diff --git a/pkg/flowcli/services/accounts.go b/pkg/flowcli/services/accounts.go index fe9b9f244..52556a4d7 100644 --- a/pkg/flowcli/services/accounts.go +++ b/pkg/flowcli/services/accounts.go @@ -420,7 +420,7 @@ func (a *Accounts) prepareTransaction( } tx.SetBlockReference(block). - SetProposer(proposer, account.Key().Index()) + SetProposer(proposer, account.DefaultKey().Index()) tx, err = tx.Sign() if err != nil { diff --git a/pkg/flowcli/services/project.go b/pkg/flowcli/services/project.go index 75da6d4a3..021df62dc 100644 --- a/pkg/flowcli/services/project.go +++ b/pkg/flowcli/services/project.go @@ -207,7 +207,7 @@ func (p *Project) Deploy(network string, update bool) ([]*contracts.Contract, er } tx.SetBlockReference(block). - SetProposer(targetAccountInfo, targetAccount.Key().Index()) + SetProposer(targetAccountInfo, targetAccount.DefaultKey().Index()) tx, err = tx.Sign() if err != nil { diff --git a/pkg/flowcli/services/transactions.go b/pkg/flowcli/services/transactions.go index f29fe5e19..a2421ab67 100644 --- a/pkg/flowcli/services/transactions.go +++ b/pkg/flowcli/services/transactions.go @@ -244,7 +244,7 @@ func (t *Transactions) Send( return nil, nil, fmt.Errorf("signer account: [%s] doesn't exists in configuration", signerName) } - signerKeyIndex := signerAccount.Key().Index() + signerKeyIndex := signerAccount.DefaultKey().Index() tx, err := t.Build( signerName, From 64d3bb59579b275933ace368d465c6d1b0b7924e Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 07:55:53 -0400 Subject: [PATCH 158/171] fix tests for removed name --- pkg/flowcli/config/config_test.go | 37 ++++++++++++++----------- pkg/flowcli/config/json/deploy_test.go | 14 ++++------ pkg/flowcli/contracts/contracts_test.go | 6 ++-- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/pkg/flowcli/config/config_test.go b/pkg/flowcli/config/config_test.go index 81db20039..d4e110e89 100644 --- a/pkg/flowcli/config/config_test.go +++ b/pkg/flowcli/config/config_test.go @@ -20,6 +20,8 @@ package config_test import ( "testing" + "github.com/onflow/cadence" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/stretchr/testify/assert" @@ -60,27 +62,30 @@ func generateComplexConfig() config.Config { Network: "testnet", }}, Deployments: config.Deployments{{ - Network: "emulator", - Account: "emulator-account", - Contracts: []config.ContractDeployment{{Name: "KittyItems", Args: nil}, {Name: "KittyItemsMarket", Args: nil}}, + Network: "emulator", + Account: "emulator-account", + Contracts: []config.ContractDeployment{ + {Name: "KittyItems", Args: []cadence.Value{}}, + {Name: "KittyItemsMarket", Args: []cadence.Value{}}, + }, }, { Network: "emulator", Account: "account-4", Contracts: []config.ContractDeployment{ - {Name: "FungibleToken", Args: nil}, - {Name: "NonFungibleToken", Args: nil}, - {Name: "Kibble", Args: nil}, - {Name: "KittyItems", Args: nil}, - {Name: "KittyItemsMarket", Args: nil}, + {Name: "FungibleToken", Args: []cadence.Value{}}, + {Name: "NonFungibleToken", Args: []cadence.Value{}}, + {Name: "Kibble", Args: []cadence.Value{}}, + {Name: "KittyItems", Args: []cadence.Value{}}, + {Name: "KittyItemsMarket", Args: []cadence.Value{}}, }, }, { Network: "testnet", Account: "account-2", Contracts: []config.ContractDeployment{ - {Name: "FungibleToken", Args: nil}, - {Name: "NonFungibleToken", Args: nil}, - {Name: "Kibble", Args: nil}, - {Name: "KittyItems", Args: nil}, + {Name: "FungibleToken", Args: []cadence.Value{}}, + {Name: "NonFungibleToken", Args: []cadence.Value{}}, + {Name: "Kibble", Args: []cadence.Value{}}, + {Name: "KittyItems", Args: []cadence.Value{}}, }, }}, Accounts: config.Accounts{{ @@ -167,10 +172,10 @@ func Test_GetDeploymentsByNetworkComplex(t *testing.T) { deployments := conf.Deployments.GetByAccountAndNetwork("account-2", "testnet") assert.Equal(t, deployments[0].Contracts, []config.ContractDeployment{ - {Name: "FungibleToken", Args: []config.ContractArgument(nil)}, - {Name: "NonFungibleToken", Args: []config.ContractArgument(nil)}, - {Name: "Kibble", Args: []config.ContractArgument(nil)}, - {Name: "KittyItems", Args: []config.ContractArgument(nil)}, + {Name: "FungibleToken", Args: []cadence.Value{}}, + {Name: "NonFungibleToken", Args: []cadence.Value{}}, + {Name: "Kibble", Args: []cadence.Value{}}, + {Name: "KittyItems", Args: []cadence.Value{}}, }) } diff --git a/pkg/flowcli/config/json/deploy_test.go b/pkg/flowcli/config/json/deploy_test.go index c6fec82a9..c53dc54c1 100644 --- a/pkg/flowcli/config/json/deploy_test.go +++ b/pkg/flowcli/config/json/deploy_test.go @@ -91,8 +91,8 @@ func Test_TransformDeployToJSON(t *testing.T) { "account-3":["KittyItems", { "name": "Kibble", "args": [ - { "name": "foo", "type": "String", "value": "Hello World" }, - { "name": "bar", "type": "Int8", "value": "10" } + { "type": "String", "value": "Hello World" }, + { "type": "Int8", "value": "10" } ] }], "account-4":["FungibleToken","NonFungibleToken","Kibble","KittyItems","KittyItemsMarket"] @@ -121,8 +121,8 @@ func Test_DeploymentAdvanced(t *testing.T) { { "name": "Kibble", "args": [ - { "name": "foo", "type": "String", "value": "Hello World" }, - { "name": "bar", "type": "Int8", "value": "10" } + { "type": "String", "value": "Hello World" }, + { "type": "Int8", "value": "10" } ] }, "KittyItemsMarket" @@ -141,10 +141,8 @@ func Test_DeploymentAdvanced(t *testing.T) { assert.Len(t, alice[0].Contracts, 2) assert.Equal(t, alice[0].Contracts[0].Name, "Kibble") assert.Len(t, alice[0].Contracts[0].Args, 2) - assert.Equal(t, alice[0].Contracts[0].Args[0].Name, "foo") - assert.Equal(t, alice[0].Contracts[0].Args[0].Arg.String(), `"Hello World"`) - assert.Equal(t, alice[0].Contracts[0].Args[1].Name, "bar") - assert.Equal(t, alice[0].Contracts[0].Args[1].Arg.String(), "10") + assert.Equal(t, alice[0].Contracts[0].Args[0].String(), `"Hello World"`) + assert.Equal(t, alice[0].Contracts[0].Args[1].String(), "10") assert.Equal(t, alice[0].Contracts[1].Name, "KittyItemsMarket") assert.Len(t, alice[0].Contracts[1].Args, 0) } diff --git a/pkg/flowcli/contracts/contracts_test.go b/pkg/flowcli/contracts/contracts_test.go index ea8a0039f..167666683 100644 --- a/pkg/flowcli/contracts/contracts_test.go +++ b/pkg/flowcli/contracts/contracts_test.go @@ -23,7 +23,7 @@ import ( "strings" "testing" - "github.com/onflow/flow-cli/pkg/flowcli/config" + "github.com/onflow/cadence" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/test" @@ -230,7 +230,7 @@ func TestResolveImports(t *testing.T) { contract.name, contract.source, contract.target, - []config.ContractArgument{}, + []cadence.Value{nil}, ) assert.NoError(t, err) } @@ -279,7 +279,7 @@ func TestContractDeploymentOrder(t *testing.T) { contract.name, contract.source, contract.target, - []config.ContractArgument{}, + []cadence.Value{nil}, ) assert.NoError(t, err) } From e419fe86724dbffb34ae328c9a3957ee208dc6a1 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 08:14:08 -0400 Subject: [PATCH 159/171] fixed docs with args --- docs/build-transactions.md | 18 +++++++++++++++++- docs/send-transactions.md | 14 +++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/docs/build-transactions.md b/docs/build-transactions.md index a4b0762cd..eb42afa1a 100644 --- a/docs/build-transactions.md +++ b/docs/build-transactions.md @@ -79,7 +79,6 @@ transaction to be executed. ## Flags - ### Payer - Flag: `--payer` @@ -115,6 +114,23 @@ Specify key index for the proposer account. Additional authorizer addresses to add to the transaction. Read more about authorizers [here](https://docs.onflow.org/concepts/accounts-and-keys/). +### Arguments + +- Flag: `--arg` +- Valid inputs: argument in `Type:Value` format. + +Arguments passed to the Cadence transaction in `Type:Value` format. +The `Type` must be the same as type in the transaction source code for that argument. + +### Arguments JSON + +- Flag: `--argsJSON` +- Valid inputs: arguments in JSON-Cadence form. + +Arguments passed to the Cadence transaction in Cadence JSON format. +Cadence JSON format contains `type` and `value` keys and is +[documented here](https://docs.onflow.org/cadence/json-cadence-spec/). + ### Host - Flag: `--host` diff --git a/docs/send-transactions.md b/docs/send-transactions.md index d06801dc8..31c582bc6 100644 --- a/docs/send-transactions.md +++ b/docs/send-transactions.md @@ -14,9 +14,9 @@ flow transactions send ## Example Usage ```shell -> flow transactions send - --signer my-testnet-account \ - --host access.testnet.nodes.onflow.org:9000 +> flow transactions send ./transaction.cdc + --args-json --args-json '[{"type": "String","value": "Hello World"}]' + --signer my-testnet-account Status ✅ SEALED ID b6430b35ba23849a8acb4fa1a4a1d5cce3ed4589111ecbb3984de1b6bd1ba39e @@ -40,7 +40,7 @@ Events: None Arguments (1): - - Argument 0: {"type":"String","value":"Meow"} + - Argument 0: {"type":"String","value":"Hello World"} Code @@ -119,9 +119,9 @@ The `Type` must be the same as type in the transaction source code for that argu - Flag: `--argsJSON` - Valid inputs: arguments in JSON-Cadence form. -Arguments passed to the Cadence transaction in `Type:Value` format. -The `Type` must be the same type as the corresponding parameter -in the Cadence transaction code. +Arguments passed to the Cadence transaction in Cadence JSON format. +Cadence JSON format contains `type` and `value` keys and is +[documented here](https://docs.onflow.org/cadence/json-cadence-spec/). ### Host From b041c8c33620b497530f128fc80512645470dedd Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 08:31:08 -0400 Subject: [PATCH 160/171] bugfix boolean arg --- pkg/flowcli/arguments.go | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pkg/flowcli/arguments.go b/pkg/flowcli/arguments.go index ced0d14f8..64f41def4 100644 --- a/pkg/flowcli/arguments.go +++ b/pkg/flowcli/arguments.go @@ -21,6 +21,7 @@ package flowcli import ( "encoding/json" "fmt" + "strconv" "strings" "github.com/onflow/cadence" @@ -60,7 +61,7 @@ func ParseArgumentsJSON(input string) ([]cadence.Value, error) { } func ParseArgumentsCommaSplit(input []string) ([]cadence.Value, error) { - args := make([]map[string]string, 0) + args := make([]map[string]interface{}, 0) if len(input) == 0 { return make([]cadence.Value, 0), nil @@ -68,6 +69,9 @@ func ParseArgumentsCommaSplit(input []string) ([]cadence.Value, error) { for _, in := range input { argInput := strings.Split(in, ":") + argType := argInput[0] + argValue := argInput[1] + if len(argInput) != 2 { return nil, fmt.Errorf( "argument not passed in correct format, correct format is: Type:Value, got %s", @@ -75,11 +79,9 @@ func ParseArgumentsCommaSplit(input []string) ([]cadence.Value, error) { ) } - argInput = sanitizeAddressArg(argInput) - - args = append(args, map[string]string{ - "value": argInput[1], - "type": argInput[0], + args = append(args, map[string]interface{}{ + "value": processValue(argType, argValue), + "type": argType, }) } jsonArgs, _ := json.Marshal(args) @@ -89,12 +91,15 @@ func ParseArgumentsCommaSplit(input []string) ([]cadence.Value, error) { } // sanitizeAddressArg sanitize address and make sure it has 0x prefix -func sanitizeAddressArg(argInput []string) []string { - if argInput[0] == "Address" && !strings.Contains(argInput[1], "0x") { - argInput[1] = fmt.Sprintf("0x%s", argInput[1]) +func processValue(argType string, argValue string) interface{} { + if argType == "Address" && !strings.Contains(argValue, "0x") { + return fmt.Sprintf("0x%s", argValue) + } else if argType == "Bool" { + converted, _ := strconv.ParseBool(argValue) + return converted } - return argInput + return argValue } func ParseArguments(args []string, argsJSON string) (scriptArgs []cadence.Value, err error) { From 0b48488c8b4e82d12a6beb25de176ecea2825b06 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 08:41:07 -0400 Subject: [PATCH 161/171] bugfix error and inline improved --- internal/transactions/transactions.go | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index 820f0f939..f62b9d483 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -61,7 +61,10 @@ func (r *TransactionResult) JSON() interface{} { if r.result != nil { result["events"] = fmt.Sprintf("%s", r.result.Events) result["status"] = r.result.Status.String() - result["error"] = r.result.Error.Error() + + if r.result.Error != nil { + result["error"] = r.result.Error.Error() + } } return result @@ -149,5 +152,13 @@ func (r *TransactionResult) String() string { // Oneliner show result as one liner grep friendly func (r *TransactionResult) Oneliner() string { - return fmt.Sprintf("ID: %s, Status: %s, Events: %s", r.tx.ID(), r.result.Status, r.result.Events) + result := fmt.Sprintf( + "ID: %s, Payer: %s, Authorizer: %s", + r.tx.ID(), r.tx.Payer, r.tx.Authorizers) + + if r.result != nil { + result += fmt.Sprintf(", Status: %s, Events: %s", r.result.Status, r.result.Events) + } + + return result } From 94261872131d545877e2cd8c116d9cdd370170fb Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 08:50:12 -0400 Subject: [PATCH 162/171] keys condition check on output preparation for decode --- internal/keys/keys.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 1a3f1f4c8..5225545b5 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -22,6 +22,7 @@ import ( "bytes" "encoding/hex" "fmt" + "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" @@ -49,7 +50,10 @@ type KeyResult struct { func (k *KeyResult) JSON() interface{} { result := make(map[string]string) result["public"] = hex.EncodeToString(k.privateKey.PublicKey().Encode()) - result["private"] = hex.EncodeToString(k.privateKey.Encode()) + + if k.privateKey != nil { + result["private"] = hex.EncodeToString(k.privateKey.Encode()) + } return result } @@ -80,5 +84,11 @@ func (k *KeyResult) String() string { // Oneliner show result as one liner grep friendly func (k *KeyResult) Oneliner() string { - return fmt.Sprintf("Private Key: %x, Public Key: %x", k.privateKey.Encode(), k.publicKey.Encode()) + result := fmt.Sprintf("Public Key: %x, ", k.publicKey.Encode()) + + if k.privateKey != nil { + result += fmt.Sprintf("Private Key: %x", k.privateKey.Encode()) + } + + return result } From cf04abda5aa72ce3db29a50df843412b23c424e3 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 08:54:56 -0400 Subject: [PATCH 163/171] release notes update --- docs/developer-updates/release-notes-v19.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/developer-updates/release-notes-v19.md b/docs/developer-updates/release-notes-v19.md index 4c52d0e22..278ca6760 100644 --- a/docs/developer-updates/release-notes-v19.md +++ b/docs/developer-updates/release-notes-v19.md @@ -5,7 +5,7 @@ Follow the [Flow CLI installation guide](https://docs.onflow.org/flow-cli/instal ## ⭐ Features ### Project Deployment with Contract Initialization Arguments -Project deployment was enhanced and it now supports providing initialization +Project deployment was improved, and it now supports providing initialization arguments during the deployment of contracts. It is easy to specify all the arguments in the configuration like so: @@ -17,8 +17,8 @@ the arguments in the configuration like so: "NonFungibleToken", { "name": "Foo", "args": [ - { "name": "greeting", "type": "String", "value": "Hello World" }, - { "name": "supply", "type": "UInt32", "value": "10" } + { "type": "String", "value": "Hello World" }, + { "type": "UInt32", "value": "10" } ] }] } @@ -91,11 +91,6 @@ having a configuration pre-initialized. Chain ID property was removed from the configuration as it is not needed anymore. With this improvement, the new configuration is less complex and shorter. -### Multiple Keys Removed -Multiple keys were removed from the account configuration making it -less complex. Should you have a rare need of specifying multiple keys -on account you can specify multiple accounts with the same address and -different keys. This new functionality is backward compatible. ## 🐞 Bug Fixes @@ -105,4 +100,12 @@ private and public keys. ### Account Key Index When Sending Transactions Account key index is now fetched from the configuration and -it doesn't default to 0 anymore. \ No newline at end of file +it doesn't default to 0 anymore. + +### Transaction Boolean Argument +Transaction boolean argument wasn't parsed correctly when passed +in comma split format. + +### Transaction JSON Output +Transaction JSON output caused a crash when the transaction +was successfully processed. \ No newline at end of file From d0ff1b297ff35763dd698b9aaf6a907b0d577dff Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 09:27:39 -0400 Subject: [PATCH 164/171] docs update revert keys and args name remove --- docs/create-accounts.md | 1 - docs/deploy-project-contracts.md | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/create-accounts.md b/docs/create-accounts.md index 5394f94fa..e2bc77119 100644 --- a/docs/create-accounts.md +++ b/docs/create-accounts.md @@ -19,7 +19,6 @@ flow accounts create # Create an account on Flow Testnet > flow accounts create \ --key a69c6986e846ba6d0....1397f5904cd319c3e01e96375d5777f1a47010 \ - --host access.testnet.nodes.onflow.org:9000 \ --signer my-testnet-account Address 0x01cf0e2f2f715450 diff --git a/docs/deploy-project-contracts.md b/docs/deploy-project-contracts.md index 28861226a..0c7dbd4d3 100644 --- a/docs/deploy-project-contracts.md +++ b/docs/deploy-project-contracts.md @@ -77,8 +77,8 @@ used during the deployment. Example: "NonFungibleToken", { "name": "Foo", "args": [ - { "name": "greeting", "type": "String", "value": "Hello World" }, - { "name": "supply", "type": "UInt32", "value": "10" } + { "type": "String", "value": "Hello World" }, + { "type": "UInt32", "value": "10" } ] }] } From 261c8350bd804bd9e5e8fea27b0f611fe75ea58a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 09:43:04 -0400 Subject: [PATCH 165/171] script execute value json fix --- internal/scripts/scripts.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index db817a9f7..578c5081e 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -21,6 +21,7 @@ package scripts import ( "bytes" "fmt" + "github.com/onflow/cadence" "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" @@ -43,7 +44,7 @@ type ScriptResult struct { // JSON convert result to JSON func (r *ScriptResult) JSON() interface{} { result := make(map[string]interface{}) - result["result"] = r.Value + result["result"] = r.Value.String() return result } From 7c8e47ae4d7be1fd28879f856cd46defc3644c9b Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 10:06:34 -0400 Subject: [PATCH 166/171] linting --- internal/accounts/accounts.go | 3 +- internal/accounts/staking-info.go | 3 +- internal/blocks/blocks.go | 3 +- internal/collections/collections.go | 6 ++-- internal/config/autocompletions.go | 11 +++--- internal/config/init.go | 1 + internal/events/events.go | 7 ++-- internal/keys/keys.go | 3 +- internal/scripts/scripts.go | 3 +- internal/status/status.go | 4 ++- internal/transactions/transactions.go | 48 +++++++++++++-------------- pkg/flowcli/config/processor.go | 2 +- pkg/flowcli/gateway/grpc.go | 1 - pkg/flowcli/output/prompt.go | 2 +- tests/mockGateway.go | 2 +- 15 files changed, 55 insertions(+), 44 deletions(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index d15fdf1e2..4cd1439d8 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -23,9 +23,10 @@ import ( "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" + + "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ diff --git a/internal/accounts/staking-info.go b/internal/accounts/staking-info.go index 3368445ab..35daaede8 100644 --- a/internal/accounts/staking-info.go +++ b/internal/accounts/staking-info.go @@ -21,13 +21,14 @@ package accounts import ( "bytes" "fmt" + "github.com/onflow/cadence" - "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli" "github.com/onflow/flow-cli/pkg/flowcli/services" + "github.com/onflow/flow-cli/pkg/flowcli/util" ) type flagsStakingInfo struct{} diff --git a/internal/blocks/blocks.go b/internal/blocks/blocks.go index 22b008f33..ddd07b618 100644 --- a/internal/blocks/blocks.go +++ b/internal/blocks/blocks.go @@ -21,12 +21,13 @@ package blocks import ( "bytes" "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/util" + "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/events" + "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ diff --git a/internal/collections/collections.go b/internal/collections/collections.go index 1c3694c2c..06bbdcf6a 100644 --- a/internal/collections/collections.go +++ b/internal/collections/collections.go @@ -21,10 +21,12 @@ package collections import ( "bytes" "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/util" + "strings" + "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" - "strings" + + "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ diff --git a/internal/config/autocompletions.go b/internal/config/autocompletions.go index f3687f47b..5fec95a48 100644 --- a/internal/config/autocompletions.go +++ b/internal/config/autocompletions.go @@ -5,8 +5,9 @@ import ( "os" "os/exec" - "github.com/onflow/flow-cli/pkg/flowcli/output" "github.com/spf13/cobra" + + "github.com/onflow/flow-cli/pkg/flowcli/output" ) var CompletionCmd = &cobra.Command{ @@ -22,24 +23,24 @@ var CompletionCmd = &cobra.Command{ } if shell == "powershell" { - cmd.Root().GenPowerShellCompletion(os.Stdout) + _ = cmd.Root().GenPowerShellCompletion(os.Stdout) } else { shell, shellOS := output.AutocompletionPrompt() if shell == "bash" && shellOS == "MacOS" { - cmd.Root().GenBashCompletionFile("/usr/local/etc/bash_completion.d/flow") + _ = cmd.Root().GenBashCompletionFile("/usr/local/etc/bash_completion.d/flow") fmt.Printf("Flow command completions installed in: /usr/local/etc/bash_completion.d/flow\n") fmt.Printf("You will need to start a new shell for this setup to take effect.\n\n") } else if shell == "bash" && shellOS == "Linux" { - cmd.Root().GenBashCompletionFile("/etc/bash_completion.d/flow") + _ = cmd.Root().GenBashCompletionFile("/etc/bash_completion.d/flow") fmt.Printf("Flow command completions installed in: /etc/bash_completion.d/flow\n") fmt.Printf("You will need to start a new shell for this setup to take effect.\n\n") } else if shell == "zsh" { c := exec.Command("zsh", "-c ", `echo -n ${fpath[1]}`) path, _ := c.Output() - cmd.Root().GenZshCompletionFile(fmt.Sprintf("%s/_flow", path)) + _ = cmd.Root().GenZshCompletionFile(fmt.Sprintf("%s/_flow", path)) fmt.Printf("Flow command completions installed in: '%s/_flow'\n", path) fmt.Printf("You will need to start a new shell for this setup to take effect.\n\n") diff --git a/internal/config/init.go b/internal/config/init.go index b7c37ed33..9c9bca1a9 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -21,6 +21,7 @@ package config import ( "bytes" "fmt" + "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/command" diff --git a/internal/events/events.go b/internal/events/events.go index 22b75fb64..e9ec97cf6 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -21,13 +21,14 @@ package events import ( "bytes" "fmt" + "io" + + "github.com/onflow/flow-cli/pkg/flowcli/util" + "github.com/onflow/cadence" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/client" "github.com/spf13/cobra" - "io" - - "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 5225545b5..739b97abc 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -23,10 +23,11 @@ import ( "encoding/hex" "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/onflow/flow-go-sdk/crypto" "github.com/spf13/cobra" + + "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index 578c5081e..640b991b3 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -23,8 +23,9 @@ import ( "fmt" "github.com/onflow/cadence" - "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/spf13/cobra" + + "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ diff --git a/internal/status/status.go b/internal/status/status.go index 2a8551976..bbb71aa89 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -21,10 +21,12 @@ package status import ( "bytes" "fmt" + + "github.com/spf13/cobra" + "github.com/onflow/flow-cli/internal/command" "github.com/onflow/flow-cli/pkg/flowcli/services" "github.com/onflow/flow-cli/pkg/flowcli/util" - "github.com/spf13/cobra" ) type FlagsStatus struct { diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index f62b9d483..6c839f518 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -22,11 +22,11 @@ import ( "bytes" "fmt" - "github.com/onflow/flow-cli/pkg/flowcli/util" "github.com/onflow/flow-go-sdk" "github.com/spf13/cobra" "github.com/onflow/flow-cli/internal/events" + "github.com/onflow/flow-cli/pkg/flowcli/util" ) var Cmd = &cobra.Command{ @@ -77,45 +77,45 @@ func (r *TransactionResult) String() string { if r.result != nil { if r.result.Error != nil { - fmt.Fprintf(writer, "❌ Transaction Error \n%s\n\n\n", r.result.Error.Error()) + _, _ = fmt.Fprintf(writer, "❌ Transaction Error \n%s\n\n\n", r.result.Error.Error()) } statusBadge := "" if r.result.Status == flow.TransactionStatusSealed { statusBadge = "✅" } - fmt.Fprintf(writer, "Status\t%s %s\n", statusBadge, r.result.Status) + _, _ = fmt.Fprintf(writer, "Status\t%s %s\n", statusBadge, r.result.Status) } - fmt.Fprintf(writer, "ID\t%s\n", r.tx.ID()) - fmt.Fprintf(writer, "Payer\t%s\n", r.tx.Payer.Hex()) - fmt.Fprintf(writer, "Authorizers\t%s\n", r.tx.Authorizers) + _, _ = fmt.Fprintf(writer, "ID\t%s\n", r.tx.ID()) + _, _ = fmt.Fprintf(writer, "Payer\t%s\n", r.tx.Payer.Hex()) + _, _ = fmt.Fprintf(writer, "Authorizers\t%s\n", r.tx.Authorizers) - fmt.Fprintf(writer, + _, _ = fmt.Fprintf(writer, "\nProposal Key:\t\n Address\t%s\n Index\t%v\n Sequence\t%v\n", r.tx.ProposalKey.Address, r.tx.ProposalKey.KeyIndex, r.tx.ProposalKey.SequenceNumber, ) if len(r.tx.PayloadSignatures) == 0 { - fmt.Fprintf(writer, "\nNo Payload Signatures\n") + _, _ = fmt.Fprintf(writer, "\nNo Payload Signatures\n") } if len(r.tx.EnvelopeSignatures) == 0 { - fmt.Fprintf(writer, "\nNo Envelope Signatures\n") + _, _ = fmt.Fprintf(writer, "\nNo Envelope Signatures\n") } for i, e := range r.tx.PayloadSignatures { - fmt.Fprintf(writer, "\nPayload Signature %v:\n", i) - fmt.Fprintf(writer, " Address\t%s\n", e.Address) - fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) - fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) + _, _ = fmt.Fprintf(writer, "\nPayload Signature %v:\n", i) + _, _ = fmt.Fprintf(writer, " Address\t%s\n", e.Address) + _, _ = fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) + _, _ = fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) } for i, e := range r.tx.EnvelopeSignatures { - fmt.Fprintf(writer, "\nEnvelope Signature %v:\n", i) - fmt.Fprintf(writer, " Address\t%s\n", e.Address) - fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) - fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) + _, _ = fmt.Fprintf(writer, "\nEnvelope Signature %v:\n", i) + _, _ = fmt.Fprintf(writer, " Address\t%s\n", e.Address) + _, _ = fmt.Fprintf(writer, " Signature\t%x\n", e.Signature) + _, _ = fmt.Fprintf(writer, " Key Index\t%d\n", e.KeyIndex) } if r.result != nil { @@ -128,25 +128,25 @@ func (r *TransactionResult) String() string { eventsOutput = "None" } - fmt.Fprintf(writer, "\n\nEvents:\t %s\n", eventsOutput) + _, _ = fmt.Fprintf(writer, "\n\nEvents:\t %s\n", eventsOutput) } if r.tx.Script != nil { if len(r.tx.Arguments) == 0 { - fmt.Fprintf(writer, "\n\nArguments\tNo arguments\n") + _, _ = fmt.Fprintf(writer, "\n\nArguments\tNo arguments\n") } else { - fmt.Fprintf(writer, "\n\nArguments (%d):\n", len(r.tx.Arguments)) + _, _ = fmt.Fprintf(writer, "\n\nArguments (%d):\n", len(r.tx.Arguments)) for i, argument := range r.tx.Arguments { - fmt.Fprintf(writer, " - Argument %d: %s\n", i, argument) + _, _ = fmt.Fprintf(writer, " - Argument %d: %s\n", i, argument) } } - fmt.Fprintf(writer, "\nCode\n\n%s\n", r.tx.Script) + _, _ = fmt.Fprintf(writer, "\nCode\n\n%s\n", r.tx.Script) } - fmt.Fprintf(writer, "\n\nPayload:\n%x", r.tx.Encode()) + _, _ = fmt.Fprintf(writer, "\n\nPayload:\n%x", r.tx.Encode()) - writer.Flush() + _ = writer.Flush() return b.String() } diff --git a/pkg/flowcli/config/processor.go b/pkg/flowcli/config/processor.go index 5bb3a617b..524584df3 100644 --- a/pkg/flowcli/config/processor.go +++ b/pkg/flowcli/config/processor.go @@ -43,7 +43,7 @@ func ProcessorRun(raw []byte) ([]byte, map[string]string) { // processEnv finds env variables and insert env values func processEnv(raw string) string { - godotenv.Load() // try to load .env file + _ = godotenv.Load() // try to load .env file raw, _ = envsubst.String(raw) return raw diff --git a/pkg/flowcli/gateway/grpc.go b/pkg/flowcli/gateway/grpc.go index c115606db..ea388e8fd 100644 --- a/pkg/flowcli/gateway/grpc.go +++ b/pkg/flowcli/gateway/grpc.go @@ -148,4 +148,3 @@ func (g *GrpcGateway) GetCollection(id flow.Identifier) (*flow.Collection, error func (g *GrpcGateway) Ping() error { return g.client.Ping(g.ctx) } - diff --git a/pkg/flowcli/output/prompt.go b/pkg/flowcli/output/prompt.go index 766ccc966..ebb07611c 100644 --- a/pkg/flowcli/output/prompt.go +++ b/pkg/flowcli/output/prompt.go @@ -115,7 +115,7 @@ func AutocompletionPrompt() (string, string) { } _, os, _ = prompt.Run() case "powershell": - fmt.Printf(`PowerShell Instalation Guide: + fmt.Printf(`PowerShell Installation Guide: PS> flow config setup-completions powershell | Out-String | Invoke-Expression # To load completions for every new session, run: diff --git a/tests/mockGateway.go b/tests/mockGateway.go index 2f5fb21e0..eea8b31e6 100644 --- a/tests/mockGateway.go +++ b/tests/mockGateway.go @@ -40,7 +40,7 @@ type MockGateway struct { GetCollectionMock func(id flow.Identifier) (*flow.Collection, error) GetBlockByHeightMock func(uint64) (*flow.Block, error) GetBlockByIDMock func(flow.Identifier) (*flow.Block, error) - PingMock func() error + PingMock func() error } func NewMockGateway() gateway.Gateway { From 1cdadd5eb29ae1b12f25b44e37b50a95f377d148 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 10:08:24 -0400 Subject: [PATCH 167/171] explicitly ignore errors on fmt --- internal/accounts/accounts.go | 16 +++++------ internal/accounts/staking-info.go | 44 ++++++++++++++--------------- internal/blocks/blocks.go | 20 ++++++------- internal/collections/collections.go | 4 +-- internal/command/command.go | 32 ++++++++++----------- internal/config/init.go | 6 ++-- internal/events/events.go | 12 ++++---- internal/keys/keys.go | 14 ++++----- internal/scripts/scripts.go | 2 +- internal/status/status.go | 6 ++-- 10 files changed, 78 insertions(+), 78 deletions(-) diff --git a/internal/accounts/accounts.go b/internal/accounts/accounts.go index 4cd1439d8..da83237cd 100644 --- a/internal/accounts/accounts.go +++ b/internal/accounts/accounts.go @@ -86,17 +86,17 @@ func (r *AccountResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - fmt.Fprintf(writer, "Address\t 0x%s\n", r.Address) - fmt.Fprintf(writer, "Balance\t %s\n", cadence.UFix64(r.Balance)) + _, _ = fmt.Fprintf(writer, "Address\t 0x%s\n", r.Address) + _, _ = fmt.Fprintf(writer, "Balance\t %s\n", cadence.UFix64(r.Balance)) - fmt.Fprintf(writer, "Keys\t %d\n", len(r.Keys)) + _, _ = fmt.Fprintf(writer, "Keys\t %d\n", len(r.Keys)) for i, key := range r.Keys { - fmt.Fprintf(writer, "\nKey %d\tPublic Key\t %x\n", i, key.PublicKey.Encode()) - fmt.Fprintf(writer, "\tWeight\t %d\n", key.Weight) - fmt.Fprintf(writer, "\tSignature Algorithm\t %s\n", key.SigAlgo) - fmt.Fprintf(writer, "\tHash Algorithm\t %s\n", key.HashAlgo) - fmt.Fprintf(writer, "\tRevoked \t %t\n", key.Revoked) + _, _ = fmt.Fprintf(writer, "\nKey %d\tPublic Key\t %x\n", i, key.PublicKey.Encode()) + _, _ = fmt.Fprintf(writer, "\tWeight\t %d\n", key.Weight) + _, _ = fmt.Fprintf(writer, "\tSignature Algorithm\t %s\n", key.SigAlgo) + _, _ = fmt.Fprintf(writer, "\tHash Algorithm\t %s\n", key.HashAlgo) + _, _ = fmt.Fprintf(writer, "\tRevoked \t %t\n", key.Revoked) fmt.Fprintf(writer, "\tSequence Number \t %d\n", key.SequenceNumber) fmt.Fprintf(writer, "\tIndex \t %d\n", key.Index) fmt.Fprintf(writer, "\n") diff --git a/internal/accounts/staking-info.go b/internal/accounts/staking-info.go index 35daaede8..4d6f7b6fe 100644 --- a/internal/accounts/staking-info.go +++ b/internal/accounts/staking-info.go @@ -78,34 +78,34 @@ func (r *StakingResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - fmt.Fprintf(writer, "Account Staking Info:\n") + _, _ = fmt.Fprintf(writer, "Account Staking Info:\n") stakingInfo := flowcli.NewStakingInfoFromValue(r.staking) - fmt.Fprintf(writer, "ID: \t %v\n", stakingInfo["id"]) - fmt.Fprintf(writer, "Initial Weight: \t %v\n", stakingInfo["initialWeight"]) - fmt.Fprintf(writer, "Networking Address: \t %v\n", stakingInfo["networkingAddress"]) - fmt.Fprintf(writer, "Networking Key: \t %v\n", stakingInfo["networkingKey"]) - fmt.Fprintf(writer, "Role: \t %v\n", stakingInfo["role"]) - fmt.Fprintf(writer, "Staking Key: \t %v\n", stakingInfo["stakingKey"]) - fmt.Fprintf(writer, "Tokens Committed: \t %v\n", stakingInfo["tokensCommitted"]) - fmt.Fprintf(writer, "Tokens To Unstake: \t %v\n", stakingInfo["tokensRequestedToUnstake"]) - fmt.Fprintf(writer, "Tokens Rewarded: \t %v\n", stakingInfo["tokensRewarded"]) - fmt.Fprintf(writer, "Tokens Staked: \t %v\n", stakingInfo["tokensStaked"]) - fmt.Fprintf(writer, "Tokens Unstaked: \t %v\n", stakingInfo["tokensUnstaked"]) - fmt.Fprintf(writer, "Tokens Unstaking: \t %v\n", stakingInfo["tokensUnstaking"]) - fmt.Fprintf(writer, "Total Tokens Staked: \t %v\n", stakingInfo["totalTokensStaked"]) + _, _ = fmt.Fprintf(writer, "ID: \t %v\n", stakingInfo["id"]) + _, _ = fmt.Fprintf(writer, "Initial Weight: \t %v\n", stakingInfo["initialWeight"]) + _, _ = fmt.Fprintf(writer, "Networking Address: \t %v\n", stakingInfo["networkingAddress"]) + _, _ = fmt.Fprintf(writer, "Networking Key: \t %v\n", stakingInfo["networkingKey"]) + _, _ = fmt.Fprintf(writer, "Role: \t %v\n", stakingInfo["role"]) + _, _ = fmt.Fprintf(writer, "Staking Key: \t %v\n", stakingInfo["stakingKey"]) + _, _ = fmt.Fprintf(writer, "Tokens Committed: \t %v\n", stakingInfo["tokensCommitted"]) + _, _ = fmt.Fprintf(writer, "Tokens To Unstake: \t %v\n", stakingInfo["tokensRequestedToUnstake"]) + _, _ = fmt.Fprintf(writer, "Tokens Rewarded: \t %v\n", stakingInfo["tokensRewarded"]) + _, _ = fmt.Fprintf(writer, "Tokens Staked: \t %v\n", stakingInfo["tokensStaked"]) + _, _ = fmt.Fprintf(writer, "Tokens Unstaked: \t %v\n", stakingInfo["tokensUnstaked"]) + _, _ = fmt.Fprintf(writer, "Tokens Unstaking: \t %v\n", stakingInfo["tokensUnstaking"]) + _, _ = fmt.Fprintf(writer, "Total Tokens Staked: \t %v\n", stakingInfo["totalTokensStaked"]) delegationStakingInfo := flowcli.NewStakingInfoFromValue(r.delegation) - fmt.Fprintf(writer, "\n\nAccount Delegation Info:\n") - fmt.Fprintf(writer, "ID: \t %v\n", delegationStakingInfo["id"]) - fmt.Fprintf(writer, "Tokens Committed: \t %v\n", delegationStakingInfo["tokensCommitted"]) - fmt.Fprintf(writer, "Tokens To Unstake: \t %v\n", delegationStakingInfo["tokensRequestedToUnstake"]) - fmt.Fprintf(writer, "Tokens Rewarded: \t %v\n", delegationStakingInfo["tokensRewarded"]) - fmt.Fprintf(writer, "Tokens Staked: \t %v\n", delegationStakingInfo["tokensStaked"]) - fmt.Fprintf(writer, "Tokens Unstaked: \t %v\n", delegationStakingInfo["tokensUnstaked"]) - fmt.Fprintf(writer, "Tokens Unstaking: \t %v\n", delegationStakingInfo["tokensUnstaking"]) + _, _ = fmt.Fprintf(writer, "\n\nAccount Delegation Info:\n") + _, _ = fmt.Fprintf(writer, "ID: \t %v\n", delegationStakingInfo["id"]) + _, _ = fmt.Fprintf(writer, "Tokens Committed: \t %v\n", delegationStakingInfo["tokensCommitted"]) + _, _ = fmt.Fprintf(writer, "Tokens To Unstake: \t %v\n", delegationStakingInfo["tokensRequestedToUnstake"]) + _, _ = fmt.Fprintf(writer, "Tokens Rewarded: \t %v\n", delegationStakingInfo["tokensRewarded"]) + _, _ = fmt.Fprintf(writer, "Tokens Staked: \t %v\n", delegationStakingInfo["tokensStaked"]) + _, _ = fmt.Fprintf(writer, "Tokens Unstaked: \t %v\n", delegationStakingInfo["tokensUnstaked"]) + _, _ = fmt.Fprintf(writer, "Tokens Unstaking: \t %v\n", delegationStakingInfo["tokensUnstaking"]) writer.Flush() return b.String() diff --git a/internal/blocks/blocks.go b/internal/blocks/blocks.go index ddd07b618..54ec3481f 100644 --- a/internal/blocks/blocks.go +++ b/internal/blocks/blocks.go @@ -82,30 +82,30 @@ func (r *BlockResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - fmt.Fprintf(writer, "Block ID\t%s\n", r.block.ID) - fmt.Fprintf(writer, "Parent ID\t%s\n", r.block.ParentID) - fmt.Fprintf(writer, "Timestamp\t%s\n", r.block.Timestamp) - fmt.Fprintf(writer, "Height\t%v\n", r.block.Height) + _, _ = fmt.Fprintf(writer, "Block ID\t%s\n", r.block.ID) + _, _ = fmt.Fprintf(writer, "Parent ID\t%s\n", r.block.ParentID) + _, _ = fmt.Fprintf(writer, "Timestamp\t%s\n", r.block.Timestamp) + _, _ = fmt.Fprintf(writer, "Height\t%v\n", r.block.Height) - fmt.Fprintf(writer, "Total Seals\t%v\n", len(r.block.Seals)) + _, _ = fmt.Fprintf(writer, "Total Seals\t%v\n", len(r.block.Seals)) - fmt.Fprintf(writer, "Total Collections\t%v\n", len(r.block.CollectionGuarantees)) + _, _ = fmt.Fprintf(writer, "Total Collections\t%v\n", len(r.block.CollectionGuarantees)) for i, guarantee := range r.block.CollectionGuarantees { - fmt.Fprintf(writer, " Collection %d:\t%s\n", i, guarantee.CollectionID) + _, _ = fmt.Fprintf(writer, " Collection %d:\t%s\n", i, guarantee.CollectionID) if r.verbose { for x, tx := range r.collections[i].TransactionIDs { - fmt.Fprintf(writer, " Transaction %d: %s\n", x, tx) + _, _ = fmt.Fprintf(writer, " Transaction %d: %s\n", x, tx) } } } if len(r.events) > 0 { - fmt.Fprintf(writer, "\n") + _, _ = fmt.Fprintf(writer, "\n") e := events.EventResult{BlockEvents: r.events} - fmt.Fprintf(writer, "%s", e.String()) + _, _ = fmt.Fprintf(writer, "%s", e.String()) } writer.Flush() diff --git a/internal/collections/collections.go b/internal/collections/collections.go index 06bbdcf6a..4e2885840 100644 --- a/internal/collections/collections.go +++ b/internal/collections/collections.go @@ -60,10 +60,10 @@ func (c *CollectionResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - fmt.Fprintf(writer, "Collection ID %s:\n", c.Collection.ID()) + _, _ = fmt.Fprintf(writer, "Collection ID %s:\n", c.Collection.ID()) for _, tx := range c.Collection.TransactionIDs { - fmt.Fprintf(writer, "%s\n", tx.String()) + _, _ = fmt.Fprintf(writer, "%s\n", tx.String()) } writer.Flush() diff --git a/internal/command/command.go b/internal/command/command.go index 4a8cc8a87..3c88975c0 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -306,9 +306,9 @@ func outputResult(result string, saveFlag string, formatFlag string, filterFlag } if formatFlag == formatInline || filterFlag != "" { - fmt.Fprintf(os.Stdout, "%s", result) + _, _ = fmt.Fprintf(os.Stdout, "%s", result) } else { // default normal output - fmt.Fprintf(os.Stdout, "\n%s\n\n", result) + _, _ = fmt.Fprintf(os.Stdout, "\n%s\n\n", result) } return nil } @@ -346,32 +346,32 @@ func handleError(description string, err error) { // handle rpc error switch t := err.(type) { case *client.RPCError: - fmt.Fprintf(os.Stderr, "❌ Grpc Error: %s \n", t.GRPCStatus().Err().Error()) + _, _ = fmt.Fprintf(os.Stderr, "❌ Grpc Error: %s \n", t.GRPCStatus().Err().Error()) default: if errors.Is(err, config.ErrOutdatedFormat) { - fmt.Fprintf(os.Stderr, "❌ Config Error: %s \n", err.Error()) - fmt.Fprintf(os.Stderr, "🙏 Please reset configuration using: 'flow init --reset'. Read more about new configuration here: https://github.com/onflow/flow-cli/releases/tag/v0.17.0") + _, _ = fmt.Fprintf(os.Stderr, "❌ Config Error: %s \n", err.Error()) + _, _ = fmt.Fprintf(os.Stderr, "🙏 Please reset configuration using: 'flow init --reset'. Read more about new configuration here: https://github.com/onflow/flow-cli/releases/tag/v0.17.0") } else if strings.Contains(err.Error(), "transport:") { - fmt.Fprintf(os.Stderr, "❌ %s \n", strings.Split(err.Error(), "transport:")[1]) - fmt.Fprintf(os.Stderr, "🙏 Make sure your emulator is running or connection address is correct.") + _, _ = fmt.Fprintf(os.Stderr, "❌ %s \n", strings.Split(err.Error(), "transport:")[1]) + _, _ = fmt.Fprintf(os.Stderr, "🙏 Make sure your emulator is running or connection address is correct.") } else if strings.Contains(err.Error(), "NotFound desc =") { - fmt.Fprintf(os.Stderr, "❌ Not Found:%s \n", strings.Split(err.Error(), "NotFound desc =")[1]) + _, _ = fmt.Fprintf(os.Stderr, "❌ Not Found:%s \n", strings.Split(err.Error(), "NotFound desc =")[1]) } else if strings.Contains(err.Error(), "code = InvalidArgument desc = ") { desc := strings.Split(err.Error(), "code = InvalidArgument desc = ") - fmt.Fprintf(os.Stderr, "❌ Invalid argument: %s \n", desc[len(desc)-1]) + _, _ = fmt.Fprintf(os.Stderr, "❌ Invalid argument: %s \n", desc[len(desc)-1]) if strings.Contains(err.Error(), "is invalid for chain") { - fmt.Fprintf(os.Stderr, "🙏 Check you are connecting to the correct network or account address you use is correct.") + _, _ = fmt.Fprintf(os.Stderr, "🙏 Check you are connecting to the correct network or account address you use is correct.") } else { - fmt.Fprintf(os.Stderr, "🙏 Check your argument and flags value, you can use --help.") + _, _ = fmt.Fprintf(os.Stderr, "🙏 Check your argument and flags value, you can use --help.") } } else if strings.Contains(err.Error(), "invalid signature:") { - fmt.Fprintf(os.Stderr, "❌ Invalid signature: %s \n", strings.Split(err.Error(), "invalid signature:")[1]) - fmt.Fprintf(os.Stderr, "🙏 Check the signer private key is provided or is in the correct format. If running emulator, make sure it's using the same configuration as this command.") + _, _ = fmt.Fprintf(os.Stderr, "❌ Invalid signature: %s \n", strings.Split(err.Error(), "invalid signature:")[1]) + _, _ = fmt.Fprintf(os.Stderr, "🙏 Check the signer private key is provided or is in the correct format. If running emulator, make sure it's using the same configuration as this command.") } else if strings.Contains(err.Error(), "signature could not be verified using public key with") { - fmt.Fprintf(os.Stderr, "❌ %s: %s \n", description, err) - fmt.Fprintf(os.Stderr, "🙏 If you are running emulator locally make sure that the emulator was started with the same config as used in this command. \nTry restarting the emulator.") + _, _ = fmt.Fprintf(os.Stderr, "❌ %s: %s \n", description, err) + _, _ = fmt.Fprintf(os.Stderr, "🙏 If you are running emulator locally make sure that the emulator was started with the same config as used in this command. \nTry restarting the emulator.") } else { - fmt.Fprintf(os.Stderr, "❌ %s: %s", description, err) + _, _ = fmt.Fprintf(os.Stderr, "❌ %s: %s", description, err) } } diff --git a/internal/config/init.go b/internal/config/init.go index 9c9bca1a9..0937c0559 100644 --- a/internal/config/init.go +++ b/internal/config/init.go @@ -83,9 +83,9 @@ func (r *InitResult) String() string { writer := util.CreateTabWriter(&b) account, _ := r.Project.EmulatorServiceAccount() - fmt.Fprintf(writer, "Configuration initialized\n") - fmt.Fprintf(writer, "Service account: %s\n\n", util.Bold("0x"+account.Address().String())) - fmt.Fprintf(writer, + _, _ = fmt.Fprintf(writer, "Configuration initialized\n") + _, _ = fmt.Fprintf(writer, "Service account: %s\n\n", util.Bold("0x"+account.Address().String())) + _, _ = fmt.Fprintf(writer, "Start emulator by running: %s \nReset configuration using: %s\n", util.Bold("'flow emulator'"), util.Bold("'flow init --reset'"), diff --git a/internal/events/events.go b/internal/events/events.go index e9ec97cf6..192f447be 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -71,9 +71,9 @@ func (e *EventResult) String() string { for _, blockEvent := range e.BlockEvents { if len(blockEvent.Events) > 0 { - fmt.Fprintf(writer, "Events Block #%v:", blockEvent.Height) + _, _ = fmt.Fprintf(writer, "Events Block #%v:", blockEvent.Height) eventsString(writer, blockEvent.Events) - fmt.Fprintf(writer, "\n") + _, _ = fmt.Fprintf(writer, "\n") } } @@ -110,10 +110,10 @@ func eventsString(writer io.Writer, events []flow.Event) { } func eventString(writer io.Writer, event flow.Event) { - fmt.Fprintf(writer, "\n Index\t%d\n", event.EventIndex) - fmt.Fprintf(writer, " Type\t%s\n", event.Type) - fmt.Fprintf(writer, " Tx ID\t%s\n", event.TransactionID) - fmt.Fprintf(writer, " Values\n") + _, _ = fmt.Fprintf(writer, "\n Index\t%d\n", event.EventIndex) + _, _ = fmt.Fprintf(writer, " Type\t%s\n", event.Type) + _, _ = fmt.Fprintf(writer, " Tx ID\t%s\n", event.TransactionID) + _, _ = fmt.Fprintf(writer, " Values\n") for i, field := range event.Value.EventType.Fields { value := event.Value.Fields[i] diff --git a/internal/keys/keys.go b/internal/keys/keys.go index 739b97abc..881b21c81 100644 --- a/internal/keys/keys.go +++ b/internal/keys/keys.go @@ -65,17 +65,17 @@ func (k *KeyResult) String() string { writer := util.CreateTabWriter(&b) if k.privateKey != nil { - fmt.Fprintf(writer, "🔴️ Store private key safely and don't share with anyone! \n") - fmt.Fprintf(writer, "Private Key \t %x \n", k.privateKey.Encode()) + _, _ = fmt.Fprintf(writer, "🔴️ Store private key safely and don't share with anyone! \n") + _, _ = fmt.Fprintf(writer, "Private Key \t %x \n", k.privateKey.Encode()) } - fmt.Fprintf(writer, "Public Key \t %x \n", k.publicKey.Encode()) + _, _ = fmt.Fprintf(writer, "Public Key \t %x \n", k.publicKey.Encode()) if k.accountKey != nil { - fmt.Fprintf(writer, "Signature algorithm \t %s\n", k.accountKey.SigAlgo) - fmt.Fprintf(writer, "Hash algorithm \t %s\n", k.accountKey.HashAlgo) - fmt.Fprintf(writer, "Weight \t %d\n", k.accountKey.Weight) - fmt.Fprintf(writer, "Revoked \t %t\n", k.accountKey.Revoked) + _, _ = fmt.Fprintf(writer, "Signature algorithm \t %s\n", k.accountKey.SigAlgo) + _, _ = fmt.Fprintf(writer, "Hash algorithm \t %s\n", k.accountKey.HashAlgo) + _, _ = fmt.Fprintf(writer, "Weight \t %d\n", k.accountKey.Weight) + _, _ = fmt.Fprintf(writer, "Revoked \t %t\n", k.accountKey.Revoked) } writer.Flush() diff --git a/internal/scripts/scripts.go b/internal/scripts/scripts.go index 640b991b3..d01e920a7 100644 --- a/internal/scripts/scripts.go +++ b/internal/scripts/scripts.go @@ -54,7 +54,7 @@ func (r *ScriptResult) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - fmt.Fprintf(writer, "Result: %s\n", r.Value) + _, _ = fmt.Fprintf(writer, "Result: %s\n", r.Value) writer.Flush() diff --git a/internal/status/status.go b/internal/status/status.go index bbb71aa89..5b1a33ea0 100644 --- a/internal/status/status.go +++ b/internal/status/status.go @@ -102,9 +102,9 @@ func (r *Result) String() string { var b bytes.Buffer writer := util.CreateTabWriter(&b) - fmt.Fprintf(writer, "Status:\t %s %s\n", r.getIcon(), r.getColoredStatus()) - fmt.Fprintf(writer, "Network:\t %s\n", r.network) - fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) + _, _ = fmt.Fprintf(writer, "Status:\t %s %s\n", r.getIcon(), r.getColoredStatus()) + _, _ = fmt.Fprintf(writer, "Network:\t %s\n", r.network) + _, _ = fmt.Fprintf(writer, "Access Node:\t %s\n", r.accessNode) writer.Flush() return b.String() From 946f37c8b89c52c1825c48a2528e365702d163c1 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 10:11:09 -0400 Subject: [PATCH 168/171] fix assign after check --- pkg/flowcli/arguments.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/flowcli/arguments.go b/pkg/flowcli/arguments.go index 64f41def4..384bfa38e 100644 --- a/pkg/flowcli/arguments.go +++ b/pkg/flowcli/arguments.go @@ -69,8 +69,6 @@ func ParseArgumentsCommaSplit(input []string) ([]cadence.Value, error) { for _, in := range input { argInput := strings.Split(in, ":") - argType := argInput[0] - argValue := argInput[1] if len(argInput) != 2 { return nil, fmt.Errorf( @@ -79,6 +77,8 @@ func ParseArgumentsCommaSplit(input []string) ([]cadence.Value, error) { ) } + argType := argInput[0] + argValue := argInput[1] args = append(args, map[string]interface{}{ "value": processValue(argType, argValue), "type": argType, From 4f0af4e6dd482b4109cc0cd157bc8c694017a57a Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 10:49:28 -0400 Subject: [PATCH 169/171] fix event json --- internal/events/events.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/internal/events/events.go b/internal/events/events.go index 192f447be..5312bf767 100644 --- a/internal/events/events.go +++ b/internal/events/events.go @@ -49,14 +49,18 @@ type EventResult struct { // JSON convert result to JSON func (e *EventResult) JSON() interface{} { - result := make(map[string]map[uint64]map[string]interface{}) + result := make([]interface{}, 0) + for _, blockEvent := range e.BlockEvents { if len(blockEvent.Events) > 0 { for _, event := range blockEvent.Events { - result["blockId"][blockEvent.Height]["index"] = event.EventIndex - result["blockId"][blockEvent.Height]["type"] = event.Type - result["blockId"][blockEvent.Height]["transactionId"] = event.TransactionID - result["blockId"][blockEvent.Height]["values"] = event.Value + result = append(result, map[string]interface{}{ + "blockID": blockEvent.Height, + "index": event.EventIndex, + "type": event.Type, + "transactionId": event.TransactionID.String(), + "values": event.Value.String(), + }) } } } From 34f5a84f89fda21f8ddfc3b3412e1538f0481ce2 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 10:51:52 -0400 Subject: [PATCH 170/171] add sending signed transaction progress --- pkg/flowcli/services/transactions.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/flowcli/services/transactions.go b/pkg/flowcli/services/transactions.go index a2421ab67..553e1cd7d 100644 --- a/pkg/flowcli/services/transactions.go +++ b/pkg/flowcli/services/transactions.go @@ -214,6 +214,9 @@ func (t *Transactions) SendSigned( return nil, nil, err } + t.logger.StartProgress(fmt.Sprintf("Sending Transaction with ID: %s", tx.FlowTransaction().ID())) + defer t.logger.StopProgress() + sentTx, err := t.gateway.SendSignedTransaction(tx) if err != nil { return nil, nil, err From bb1406400a510f1087def66e8e350c3327487284 Mon Sep 17 00:00:00 2001 From: Gregor Gololicic Date: Fri, 30 Apr 2021 11:02:27 -0400 Subject: [PATCH 171/171] add missing headers --- internal/config/autocompletions.go | 18 ++++++++++++++++++ pkg/flowcli/config/parsers.go | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/internal/config/autocompletions.go b/internal/config/autocompletions.go index 5fec95a48..4376af148 100644 --- a/internal/config/autocompletions.go +++ b/internal/config/autocompletions.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import ( diff --git a/pkg/flowcli/config/parsers.go b/pkg/flowcli/config/parsers.go index e7aaaad25..a66b52563 100644 --- a/pkg/flowcli/config/parsers.go +++ b/pkg/flowcli/config/parsers.go @@ -1,3 +1,21 @@ +/* + * Flow CLI + * + * Copyright 2019-2021 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 config import (