diff --git a/internal/transactions/get-system.go b/internal/transactions/get-system.go new file mode 100644 index 000000000..ac1856085 --- /dev/null +++ b/internal/transactions/get-system.go @@ -0,0 +1,80 @@ +/* + * Flow CLI + * + * Copyright Flow Foundation + * + * 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 ( + "context" + + "github.com/spf13/cobra" + + "github.com/onflow/flowkit/v2" + "github.com/onflow/flowkit/v2/output" + + "github.com/onflow/flow-cli/internal/command" +) + +type flagsGetSystem struct { + Include []string `default:"" flag:"include" info:"Fields to include in the output. Valid values: signatures, code, payload, fee-events."` + Exclude []string `default:"" flag:"exclude" info:"Fields to exclude from the output. Valid values: events."` +} + +var getSystemFlags = flagsGetSystem{} + +var getSystemCommand = &command.Command{ + Cmd: &cobra.Command{ + Use: "get-system ", + Short: "Get the system transaction by block info", + Example: "flow transactions get-system a1b2c3...", + Args: cobra.ExactArgs(1), + }, + Flags: &getSystemFlags, + Run: getSystemTransaction, +} + +func getSystemTransaction( + args []string, + _ command.GlobalFlags, + logger output.Logger, + _ flowkit.ReaderWriter, + flow flowkit.Services, +) (command.Result, error) { + query, err := flowkit.NewBlockQuery(args[0]) + if err != nil { + return nil, err + } + + logger.StartProgress("Fetching Block...") + defer logger.StopProgress() + block, err := flow.GetBlock(context.Background(), query) + if err != nil { + return nil, err + } + + tx, result, err := flow.GetSystemTransaction(context.Background(), block.ID) + if err != nil { + return nil, err + } + + return &transactionResult{ + result: result, + tx: tx, + include: getSystemFlags.Include, + exclude: getSystemFlags.Exclude, + }, nil +} diff --git a/internal/transactions/transactions.go b/internal/transactions/transactions.go index fb195fb2b..63da701c0 100644 --- a/internal/transactions/transactions.go +++ b/internal/transactions/transactions.go @@ -49,6 +49,7 @@ func init() { signCommand.AddToParent(Cmd) buildCommand.AddToParent(Cmd) sendSignedCommand.AddToParent(Cmd) + getSystemCommand.AddToParent(Cmd) decodeCommand.AddToParent(Cmd) } diff --git a/internal/transactions/transactions_test.go b/internal/transactions/transactions_test.go index fd7d635c4..b69eb0d14 100644 --- a/internal/transactions/transactions_test.go +++ b/internal/transactions/transactions_test.go @@ -138,6 +138,44 @@ func Test_Get(t *testing.T) { }) } +func Test_GetSystem(t *testing.T) { + srv, _, rw := util.TestMocks(t) + + t.Run("Success", func(t *testing.T) { + inArgs := []string{"100"} + + returnBlock := tests.NewBlock() + returnBlock.Height = uint64(100) + + srv.GetBlock.Run(func(args mock.Arguments) { + assert.Equal(t, uint64(100), args.Get(1).(flowkit.BlockQuery).Height) + }).Return(returnBlock, nil) + + srv.GetSystemTransaction.Return(nil, nil, nil) + + res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, rw, srv.Mock) + assert.NoError(t, err) + assert.NotNil(t, res) + }) + + t.Run("Fail invalid block ID", func(t *testing.T) { + inArgs := []string{""} + + returnBlock := tests.NewBlock() + returnBlock.Height = uint64(100) + + srv.GetBlock.Run(func(args mock.Arguments) { + assert.Equal(t, uint64(100), args.Get(1).(flowkit.BlockQuery).Height) + }).Return(returnBlock, nil) + + srv.GetSystemTransaction.Return(nil, nil, fmt.Errorf("block not found")) + + res, err := getSystemTransaction(inArgs, command.GlobalFlags{}, util.NoLogger, rw, srv.Mock) + assert.Error(t, err) + assert.Nil(t, res) + }) +} + func Test_Send(t *testing.T) { srv, state, _ := util.TestMocks(t)