code.vegaprotocol.io/vega@v0.79.0/wallet/tests/commands_for_test.go (about)

     1  // Copyright (C) 2023 Gobalsky Labs Limited
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU Affero General Public License as
     5  // published by the Free Software Foundation, either version 3 of the
     6  // License, or (at your option) any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU Affero General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU Affero General Public License
    14  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15  
    16  package tests_test
    17  
    18  import (
    19  	"bufio"
    20  	"bytes"
    21  	"encoding/json"
    22  	"fmt"
    23  	"sort"
    24  	"strings"
    25  	"testing"
    26  	"time"
    27  
    28  	cmd "code.vegaprotocol.io/vega/cmd/vegawallet/commands"
    29  
    30  	"github.com/stretchr/testify/assert"
    31  )
    32  
    33  func ExecuteCmd(t *testing.T, args []string) ([]byte, error) {
    34  	t.Helper()
    35  	var output bytes.Buffer
    36  	w := bufio.NewWriter(&output)
    37  	c := cmd.NewCmdRoot(w)
    38  	c.SetArgs(args)
    39  	execErr := c.Execute()
    40  	if err := w.Flush(); err != nil {
    41  		t.Fatalf("couldn't flush data out of command writer: %v", err)
    42  	}
    43  	return output.Bytes(), execErr
    44  }
    45  
    46  func Command(t *testing.T, args []string) error {
    47  	t.Helper()
    48  	argsWithCmd := []string{"command"}
    49  	argsWithCmd = append(argsWithCmd, args...)
    50  	_, err := ExecuteCmd(t, argsWithCmd)
    51  	if err != nil {
    52  		return err
    53  	}
    54  	return nil
    55  }
    56  
    57  func Init(t *testing.T, args []string) error {
    58  	t.Helper()
    59  	argsWithCmd := []string{"init"}
    60  	argsWithCmd = append(argsWithCmd, args...)
    61  	_, err := ExecuteCmd(t, argsWithCmd)
    62  	return err
    63  }
    64  
    65  func KeyAnnotate(t *testing.T, args []string) error {
    66  	t.Helper()
    67  	argsWithCmd := []string{"key", "annotate"}
    68  	argsWithCmd = append(argsWithCmd, args...)
    69  	_, err := ExecuteCmd(t, argsWithCmd)
    70  	if err != nil {
    71  		return err
    72  	}
    73  	return nil
    74  }
    75  
    76  type GenerateKeyResponse struct {
    77  	PublicKey string `json:"publicKey"`
    78  	Algorithm struct {
    79  		Name    string `json:"name"`
    80  		Version uint32 `json:"version"`
    81  	} `json:"algorithm"`
    82  	Metadata []struct {
    83  		Key   string `json:"key"`
    84  		Value string `json:"value"`
    85  	} `json:"metadata"`
    86  }
    87  
    88  func KeyGenerate(t *testing.T, args []string) (*GenerateKeyResponse, error) {
    89  	t.Helper()
    90  	argsWithCmd := []string{"key", "generate"}
    91  	argsWithCmd = append(argsWithCmd, args...)
    92  	output, err := ExecuteCmd(t, argsWithCmd)
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	resp := &GenerateKeyResponse{}
    97  	if err := json.Unmarshal(output, resp); err != nil {
    98  		t.Fatalf("couldn't unmarshal command output: %v", err)
    99  	}
   100  	return resp, nil
   101  }
   102  
   103  type GenerateKeyAssertion struct {
   104  	t    *testing.T
   105  	resp *GenerateKeyResponse
   106  }
   107  
   108  func AssertGenerateKey(t *testing.T, resp *GenerateKeyResponse) *GenerateKeyAssertion {
   109  	t.Helper()
   110  
   111  	assert.NotNil(t, resp)
   112  	assert.NotEmpty(t, resp.PublicKey)
   113  	assert.Equal(t, "vega/ed25519", resp.Algorithm.Name)
   114  	assert.Equal(t, uint32(1), resp.Algorithm.Version)
   115  
   116  	return &GenerateKeyAssertion{
   117  		t:    t,
   118  		resp: resp,
   119  	}
   120  }
   121  
   122  func (a *GenerateKeyAssertion) WithMetadata(expected map[string]string) *GenerateKeyAssertion {
   123  	meta := map[string]string{}
   124  	for _, m := range a.resp.Metadata {
   125  		meta[m.Key] = m.Value
   126  	}
   127  	assert.Equal(a.t, expected, meta)
   128  	return a
   129  }
   130  
   131  func (a *GenerateKeyAssertion) WithPublicKey(expected string) *GenerateKeyAssertion {
   132  	assert.Equal(a.t, expected, a.resp.PublicKey)
   133  	return a
   134  }
   135  
   136  type ListKeysResponse struct {
   137  	Keys []struct {
   138  		Name      string `json:"name"`
   139  		PublicKey string `json:"publicKey"`
   140  	} `json:"keys"`
   141  }
   142  
   143  func KeyList(t *testing.T, args []string) (*ListKeysResponse, error) {
   144  	t.Helper()
   145  	argsWithCmd := []string{"key", "list"}
   146  	argsWithCmd = append(argsWithCmd, args...)
   147  	output, err := ExecuteCmd(t, argsWithCmd)
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  	resp := &ListKeysResponse{}
   152  	if err := json.Unmarshal(output, resp); err != nil {
   153  		t.Fatalf("couldn't unmarshal command output: %v", err)
   154  	}
   155  	return resp, nil
   156  }
   157  
   158  type DescribeKeyResponse struct {
   159  	PublicKey string `json:"publicKey"`
   160  
   161  	Algorithm struct {
   162  		Name    string `json:"name"`
   163  		Version uint32 `json:"version"`
   164  	} `json:"algorithm"`
   165  	Metadata []struct {
   166  		Key   string `json:"key"`
   167  		Value string `json:"value"`
   168  	} `json:"metadata"`
   169  	IsTainted bool `json:"isTainted"`
   170  }
   171  
   172  func KeyDescribe(t *testing.T, args []string) (*DescribeKeyResponse, error) {
   173  	t.Helper()
   174  	argsWithCmd := []string{"key", "describe"}
   175  	argsWithCmd = append(argsWithCmd, args...)
   176  	output, err := ExecuteCmd(t, argsWithCmd)
   177  	if err != nil {
   178  		return nil, err
   179  	}
   180  	resp := &DescribeKeyResponse{}
   181  	if err := json.Unmarshal(output, resp); err != nil {
   182  		t.Fatalf("couldn't unmarshal command output: %v", err)
   183  	}
   184  	return resp, nil
   185  }
   186  
   187  type DescribeKeyAssertion struct {
   188  	t    *testing.T
   189  	resp *DescribeKeyResponse
   190  }
   191  
   192  func AssertDescribeKey(t *testing.T, resp *DescribeKeyResponse) *DescribeKeyAssertion {
   193  	t.Helper()
   194  
   195  	assert.NotNil(t, resp)
   196  	assert.NotEmpty(t, resp.PublicKey)
   197  	assert.NotEmpty(t, resp.Algorithm.Name)
   198  	assert.NotEmpty(t, resp.Algorithm.Version)
   199  
   200  	return &DescribeKeyAssertion{
   201  		t:    t,
   202  		resp: resp,
   203  	}
   204  }
   205  
   206  func (d *DescribeKeyAssertion) WithPubKey(pubkey string) *DescribeKeyAssertion {
   207  	assert.Equal(d.t, pubkey, d.resp.PublicKey)
   208  	return d
   209  }
   210  
   211  func (d *DescribeKeyAssertion) WithAlgorithm(name string, version uint32) *DescribeKeyAssertion {
   212  	assert.Equal(d.t, name, d.resp.Algorithm.Name)
   213  	assert.Equal(d.t, version, d.resp.Algorithm.Version)
   214  	return d
   215  }
   216  
   217  func (d *DescribeKeyAssertion) WithTainted(tainted bool) *DescribeKeyAssertion {
   218  	assert.Equal(d.t, tainted, d.resp.IsTainted)
   219  	return d
   220  }
   221  
   222  func (d *DescribeKeyAssertion) WithMeta(expected map[string]string) *DescribeKeyAssertion {
   223  	meta := map[string]string{}
   224  	for _, m := range d.resp.Metadata {
   225  		meta[m.Key] = m.Value
   226  	}
   227  	assert.Equal(d.t, expected, meta)
   228  	return d
   229  }
   230  
   231  type IsolateKeyResponse struct {
   232  	Wallet   string `json:"wallet"`
   233  	FilePath string `json:"filePath"`
   234  }
   235  
   236  func KeyIsolate(t *testing.T, args []string) (*IsolateKeyResponse, error) {
   237  	t.Helper()
   238  	argsWithCmd := []string{"key", "isolate"}
   239  	argsWithCmd = append(argsWithCmd, args...)
   240  	output, err := ExecuteCmd(t, argsWithCmd)
   241  	if err != nil {
   242  		return nil, err
   243  	}
   244  	resp := &IsolateKeyResponse{}
   245  	if err := json.Unmarshal(output, resp); err != nil {
   246  		t.Fatalf("couldn't unmarshal command output: %v", err)
   247  	}
   248  	return resp, nil
   249  }
   250  
   251  type IsolateKeyAssertion struct {
   252  	t    *testing.T
   253  	resp *IsolateKeyResponse
   254  }
   255  
   256  func AssertIsolateKey(t *testing.T, resp *IsolateKeyResponse) *IsolateKeyAssertion {
   257  	t.Helper()
   258  
   259  	assert.NotNil(t, resp)
   260  	assert.NotEmpty(t, resp.Wallet)
   261  	assert.NotEmpty(t, resp.FilePath)
   262  	assert.FileExists(t, resp.FilePath)
   263  
   264  	return &IsolateKeyAssertion{
   265  		t:    t,
   266  		resp: resp,
   267  	}
   268  }
   269  
   270  func (a *IsolateKeyAssertion) WithSpecialName(wallet, pubkey string) *IsolateKeyAssertion {
   271  	assert.Equal(a.t, fmt.Sprintf("%s.%s.isolated", wallet, pubkey[0:8]), a.resp.Wallet)
   272  	return a
   273  }
   274  
   275  func (a *IsolateKeyAssertion) LocatedUnder(home string) *IsolateKeyAssertion {
   276  	assert.True(a.t, strings.HasPrefix(a.resp.FilePath, home), "wallet has not been imported under home directory")
   277  	return a
   278  }
   279  
   280  func KeyTaint(t *testing.T, args []string) error {
   281  	t.Helper()
   282  	argsWithCmd := []string{"key", "taint"}
   283  	argsWithCmd = append(argsWithCmd, args...)
   284  	_, err := ExecuteCmd(t, argsWithCmd)
   285  	if err != nil {
   286  		return err
   287  	}
   288  	return nil
   289  }
   290  
   291  type KeyRotateResponse struct {
   292  	MasterPublicKey    string `json:"masterPublicKey"`
   293  	EncodedTransaction string `json:"encodedTransaction"`
   294  }
   295  
   296  func KeyRotate(t *testing.T, args []string) (*KeyRotateResponse, error) {
   297  	t.Helper()
   298  	argsWithCmd := []string{"key", "rotate"}
   299  	argsWithCmd = append(argsWithCmd, args...)
   300  	output, err := ExecuteCmd(t, argsWithCmd)
   301  	if err != nil {
   302  		return nil, err
   303  	}
   304  	resp := &KeyRotateResponse{}
   305  	if err := json.Unmarshal(output, resp); err != nil {
   306  		t.Fatalf("couldn't unmarshal command output: %v", err)
   307  	}
   308  	return resp, nil
   309  }
   310  
   311  type KeyRotateAssertion struct {
   312  	t    *testing.T
   313  	resp *KeyRotateResponse
   314  }
   315  
   316  func AssertKeyRotate(t *testing.T, resp *KeyRotateResponse) *KeyRotateAssertion {
   317  	t.Helper()
   318  
   319  	assert.NotNil(t, resp)
   320  	assert.NotEmpty(t, resp.EncodedTransaction)
   321  	assert.NotEmpty(t, resp.MasterPublicKey)
   322  
   323  	return &KeyRotateAssertion{
   324  		t:    t,
   325  		resp: resp,
   326  	}
   327  }
   328  
   329  func KeyUntaint(t *testing.T, args []string) error {
   330  	t.Helper()
   331  	argsWithCmd := []string{"key", "untaint"}
   332  	argsWithCmd = append(argsWithCmd, args...)
   333  	_, err := ExecuteCmd(t, argsWithCmd)
   334  	if err != nil {
   335  		return err
   336  	}
   337  	return nil
   338  }
   339  
   340  type ImportNetworkResponse struct {
   341  	Name     string `json:"name"`
   342  	FilePath string `json:"filePath"`
   343  }
   344  
   345  func NetworkImport(t *testing.T, args []string) (*ImportNetworkResponse, error) {
   346  	t.Helper()
   347  	argsWithCmd := []string{"network", "import"}
   348  	argsWithCmd = append(argsWithCmd, args...)
   349  	output, err := ExecuteCmd(t, argsWithCmd)
   350  	if err != nil {
   351  		return nil, err
   352  	}
   353  	resp := &ImportNetworkResponse{}
   354  	if err := json.Unmarshal(output, resp); err != nil {
   355  		t.Fatalf("couldn't unmarshal command output: %v", err)
   356  	}
   357  	return resp, nil
   358  }
   359  
   360  type ImportNetworkAssertion struct {
   361  	t    *testing.T
   362  	resp *ImportNetworkResponse
   363  }
   364  
   365  func AssertImportNetwork(t *testing.T, resp *ImportNetworkResponse) *ImportNetworkAssertion {
   366  	t.Helper()
   367  
   368  	assert.NotNil(t, resp)
   369  	assert.NotEmpty(t, resp.Name)
   370  	assert.NotEmpty(t, resp.FilePath)
   371  	assert.FileExists(t, resp.FilePath)
   372  
   373  	return &ImportNetworkAssertion{
   374  		t:    t,
   375  		resp: resp,
   376  	}
   377  }
   378  
   379  func (a *ImportNetworkAssertion) WithName(expected string) *ImportNetworkAssertion {
   380  	assert.Equal(a.t, expected, a.resp.Name)
   381  	return a
   382  }
   383  
   384  func (a *ImportNetworkAssertion) LocatedUnder(home string) *ImportNetworkAssertion {
   385  	assert.True(a.t, strings.HasPrefix(a.resp.FilePath, home), "wallet has not been imported under home directory")
   386  	return a
   387  }
   388  
   389  type LocateNetworksResponse struct {
   390  	Path string `json:"path"`
   391  }
   392  
   393  func NetworkLocate(t *testing.T, args []string) (*LocateNetworksResponse, error) {
   394  	t.Helper()
   395  	argsWithCmd := []string{"network", "locate"}
   396  	argsWithCmd = append(argsWithCmd, args...)
   397  	output, err := ExecuteCmd(t, argsWithCmd)
   398  	if err != nil {
   399  		return nil, err
   400  	}
   401  	resp := &LocateNetworksResponse{}
   402  	if err := json.Unmarshal(output, resp); err != nil {
   403  		t.Fatalf("couldn't unmarshal command output: %v", err)
   404  	}
   405  	return resp, nil
   406  }
   407  
   408  type LocateNetworkAssertion struct {
   409  	t    *testing.T
   410  	resp *LocateNetworksResponse
   411  }
   412  
   413  func AssertLocateNetwork(t *testing.T, resp *LocateNetworksResponse) *LocateNetworkAssertion {
   414  	t.Helper()
   415  
   416  	assert.NotNil(t, resp)
   417  
   418  	return &LocateNetworkAssertion{
   419  		t:    t,
   420  		resp: resp,
   421  	}
   422  }
   423  
   424  func (a *LocateNetworkAssertion) LocatedUnder(p string) *LocateNetworkAssertion {
   425  	assert.True(a.t, strings.HasPrefix(a.resp.Path, p), "path returned doesn't start with home path")
   426  	return a
   427  }
   428  
   429  type ListNetworksResponse struct {
   430  	Networks []ListNetworkResponse `json:"networks"`
   431  }
   432  
   433  type ListNetworkResponse struct {
   434  	Name     string                        `json:"name"`
   435  	Metadata []ListNetworkMetadataResponse `json:"metadata"`
   436  }
   437  
   438  type ListNetworkMetadataResponse struct {
   439  	Key   string `json:"key"`
   440  	Value string `json:"value"`
   441  }
   442  
   443  func NetworkList(t *testing.T, args []string) (*ListNetworksResponse, error) {
   444  	t.Helper()
   445  	argsWithCmd := []string{"network", "list"}
   446  	argsWithCmd = append(argsWithCmd, args...)
   447  	output, err := ExecuteCmd(t, argsWithCmd)
   448  	if err != nil {
   449  		return nil, err
   450  	}
   451  	resp := &ListNetworksResponse{}
   452  	if err := json.Unmarshal(output, resp); err != nil {
   453  		t.Fatalf("couldn't unmarshal command output: %v", err)
   454  	}
   455  	return resp, nil
   456  }
   457  
   458  type ListNetworkAssertion struct {
   459  	t    *testing.T
   460  	resp *ListNetworksResponse
   461  }
   462  
   463  func AssertListNetwork(t *testing.T, resp *ListNetworksResponse) *ListNetworkAssertion {
   464  	t.Helper()
   465  
   466  	assert.NotNil(t, resp)
   467  
   468  	return &ListNetworkAssertion{
   469  		t:    t,
   470  		resp: resp,
   471  	}
   472  }
   473  
   474  func (a *ListNetworkAssertion) WithNetworks(networks ...string) *ListNetworkAssertion {
   475  	sort.Strings(networks)
   476  	nets := make([]string, 0, len(networks))
   477  	for _, net := range a.resp.Networks {
   478  		nets = append(nets, net.Name)
   479  	}
   480  	assert.Equal(a.t, networks, nets)
   481  	return a
   482  }
   483  
   484  func (a *ListNetworkAssertion) WithoutNetwork() *ListNetworkAssertion {
   485  	assert.Empty(a.t, a.resp.Networks)
   486  	return a
   487  }
   488  
   489  func NetworkDelete(t *testing.T, args []string) error {
   490  	t.Helper()
   491  	argsWithCmd := []string{"network", "delete"}
   492  	argsWithCmd = append(argsWithCmd, args...)
   493  	_, err := ExecuteCmd(t, argsWithCmd)
   494  	return err
   495  }
   496  
   497  type DescribeNetworkResponse struct {
   498  	Name        string `json:"name"`
   499  	Level       string `json:"logLevel"`
   500  	TokenExpiry string `json:"tokenExpiry"`
   501  	Port        int    `json:"port"`
   502  	Host        string `json:"host"`
   503  	API         struct {
   504  		GRPCConfig struct {
   505  			Hosts   []string `json:"hosts"`
   506  			Retries uint64   `json:"retries"`
   507  		} `json:"grpc"`
   508  		RESTConfig struct {
   509  			Hosts []string `json:"hosts"`
   510  		} `json:"rest"`
   511  		GraphQLConfig struct {
   512  			Hosts []string `json:"hosts"`
   513  		} `json:"graphQL"`
   514  	} `json:"api"`
   515  }
   516  
   517  func NetworkDescribe(t *testing.T, args []string) (*DescribeNetworkResponse, error) {
   518  	t.Helper()
   519  	argsWithCmd := []string{"network", "describe"}
   520  	argsWithCmd = append(argsWithCmd, args...)
   521  	output, err := ExecuteCmd(t, argsWithCmd)
   522  	if err != nil {
   523  		return nil, err
   524  	}
   525  	resp := &DescribeNetworkResponse{}
   526  	if err := json.Unmarshal(output, resp); err != nil {
   527  		t.Fatalf("couldn't unmarshal command output: %v", err)
   528  	}
   529  	return resp, nil
   530  }
   531  
   532  type DescribeNetworkAssertion struct {
   533  	t    *testing.T
   534  	resp *DescribeNetworkResponse
   535  }
   536  
   537  func AssertDescribeNetwork(t *testing.T, resp *DescribeNetworkResponse) *DescribeNetworkAssertion {
   538  	t.Helper()
   539  
   540  	assert.NotNil(t, resp)
   541  	assert.NotEmpty(t, resp.Name)
   542  
   543  	return &DescribeNetworkAssertion{
   544  		t:    t,
   545  		resp: resp,
   546  	}
   547  }
   548  
   549  func (d *DescribeNetworkAssertion) WithName(expected string) *DescribeNetworkAssertion {
   550  	assert.Equal(d.t, expected, d.resp.Name)
   551  	return d
   552  }
   553  
   554  func (d *DescribeNetworkAssertion) WithGRPCConfig(hosts []string) *DescribeNetworkAssertion {
   555  	assert.Equal(d.t, hosts, d.resp.API.GRPCConfig.Hosts)
   556  	return d
   557  }
   558  
   559  func (d *DescribeNetworkAssertion) WithGraphQLConfig(hosts []string) *DescribeNetworkAssertion {
   560  	assert.Equal(d.t, hosts, d.resp.API.GraphQLConfig.Hosts)
   561  	return d
   562  }
   563  
   564  func (d *DescribeNetworkAssertion) WithRESTConfig(hosts []string) *DescribeNetworkAssertion {
   565  	assert.Equal(d.t, hosts, d.resp.API.RESTConfig.Hosts)
   566  	return d
   567  }
   568  
   569  type SignCommandResponse struct {
   570  	EncodedTransaction string `json:"encodedTransaction"`
   571  }
   572  
   573  func SignCommand(t *testing.T, args []string) (*SignCommandResponse, error) {
   574  	t.Helper()
   575  	argsWithCmd := []string{"transaction", "sign"}
   576  	argsWithCmd = append(argsWithCmd, args...)
   577  	output, err := ExecuteCmd(t, argsWithCmd)
   578  	if err != nil {
   579  		return nil, err
   580  	}
   581  	resp := &SignCommandResponse{}
   582  	if err := json.Unmarshal(output, resp); err != nil {
   583  		t.Fatalf("couldn't unmarshal command output: %v", err)
   584  	}
   585  	return resp, nil
   586  }
   587  
   588  type SignCommandAssertion struct {
   589  	t    *testing.T
   590  	resp *SignCommandResponse
   591  }
   592  
   593  func AssertSignCommand(t *testing.T, resp *SignCommandResponse) *SignCommandAssertion {
   594  	t.Helper()
   595  
   596  	assert.NotNil(t, resp)
   597  	assert.NotEmpty(t, resp.EncodedTransaction)
   598  	assert.NotEmpty(t, resp.EncodedTransaction)
   599  
   600  	return &SignCommandAssertion{
   601  		t:    t,
   602  		resp: resp,
   603  	}
   604  }
   605  
   606  type SignMessageResponse struct {
   607  	Signature string `json:"signature"`
   608  }
   609  
   610  func SignMessage(t *testing.T, args []string) (*SignMessageResponse, error) {
   611  	t.Helper()
   612  	argsWithCmd := []string{"message", "sign"}
   613  	argsWithCmd = append(argsWithCmd, args...)
   614  	output, err := ExecuteCmd(t, argsWithCmd)
   615  	if err != nil {
   616  		return nil, err
   617  	}
   618  	resp := &SignMessageResponse{}
   619  	if err := json.Unmarshal(output, resp); err != nil {
   620  		t.Fatalf("couldn't unmarshal command output: %v", err)
   621  	}
   622  	return resp, nil
   623  }
   624  
   625  type SignMessageAssertion struct {
   626  	t    *testing.T
   627  	resp *SignMessageResponse
   628  }
   629  
   630  func AssertSignMessage(t *testing.T, resp *SignMessageResponse) *SignMessageAssertion {
   631  	t.Helper()
   632  
   633  	assert.NotNil(t, resp)
   634  	assert.NotEmpty(t, resp.Signature)
   635  
   636  	return &SignMessageAssertion{
   637  		t:    t,
   638  		resp: resp,
   639  	}
   640  }
   641  
   642  func (a *SignMessageAssertion) WithSignature(expected string) *SignMessageAssertion {
   643  	assert.Equal(a.t, expected, a.resp.Signature)
   644  	return a
   645  }
   646  
   647  type VerifyMessageResponse struct {
   648  	IsValid bool `json:"isValid"`
   649  }
   650  
   651  func VerifyMessage(t *testing.T, args []string) (*VerifyMessageResponse, error) {
   652  	t.Helper()
   653  	argsWithCmd := []string{"message", "verify"}
   654  	argsWithCmd = append(argsWithCmd, args...)
   655  	output, err := ExecuteCmd(t, argsWithCmd)
   656  	if err != nil {
   657  		return nil, err
   658  	}
   659  	resp := &VerifyMessageResponse{}
   660  	if err := json.Unmarshal(output, resp); err != nil {
   661  		t.Fatalf("couldn't unmarshal command output: %v", err)
   662  	}
   663  	return resp, nil
   664  }
   665  
   666  type VerifyAssertion struct {
   667  	t    *testing.T
   668  	resp *VerifyMessageResponse
   669  }
   670  
   671  func AssertVerifyMessage(t *testing.T, resp *VerifyMessageResponse) *VerifyAssertion {
   672  	t.Helper()
   673  
   674  	assert.NotNil(t, resp)
   675  
   676  	return &VerifyAssertion{
   677  		t:    t,
   678  		resp: resp,
   679  	}
   680  }
   681  
   682  func (a *VerifyAssertion) IsValid() *VerifyAssertion {
   683  	assert.True(a.t, a.resp.IsValid)
   684  	return a
   685  }
   686  
   687  type CreateWalletResponse struct {
   688  	Wallet struct {
   689  		Name                 string `json:"name"`
   690  		RecoveryPhrase       string `json:"recoveryPhrase"`
   691  		KeyDerivationVersion uint32 `json:"keyDerivationVersion"`
   692  		FilePath             string `json:"filePath"`
   693  	} `json:"wallet"`
   694  	Key struct {
   695  		PublicKey string `json:"publicKey"`
   696  		Algorithm struct {
   697  			Name    string `json:"name"`
   698  			Version uint32 `json:"version"`
   699  		} `json:"algorithm"`
   700  		Meta []struct {
   701  			Key   string `json:"key"`
   702  			Value string `json:"value"`
   703  		} `json:"meta"`
   704  	} `json:"key"`
   705  }
   706  
   707  func WalletCreate(t *testing.T, args []string) (*CreateWalletResponse, error) {
   708  	t.Helper()
   709  	argsWithCmd := []string{"create"}
   710  	argsWithCmd = append(argsWithCmd, args...)
   711  	output, err := ExecuteCmd(t, argsWithCmd)
   712  	if err != nil {
   713  		return nil, err
   714  	}
   715  	resp := &CreateWalletResponse{}
   716  	if err := json.Unmarshal(output, resp); err != nil {
   717  		t.Fatalf("couldn't unmarshal command output: %v", err)
   718  	}
   719  	return resp, nil
   720  }
   721  
   722  type CreateWalletAssertion struct {
   723  	t    *testing.T
   724  	resp *CreateWalletResponse
   725  }
   726  
   727  func AssertCreateWallet(t *testing.T, resp *CreateWalletResponse) *CreateWalletAssertion {
   728  	t.Helper()
   729  
   730  	assert.NotNil(t, resp)
   731  	assert.NotEmpty(t, resp.Wallet.Name)
   732  	assert.NotEmpty(t, resp.Wallet.RecoveryPhrase)
   733  	assert.Equal(t, uint32(2), resp.Wallet.KeyDerivationVersion)
   734  	assert.NotEmpty(t, resp.Wallet.FilePath)
   735  	assert.FileExists(t, resp.Wallet.FilePath)
   736  	assert.NotEmpty(t, resp.Key.PublicKey)
   737  	assert.Equal(t, "vega/ed25519", resp.Key.Algorithm.Name)
   738  	assert.Equal(t, uint32(1), resp.Key.Algorithm.Version)
   739  
   740  	return &CreateWalletAssertion{
   741  		t:    t,
   742  		resp: resp,
   743  	}
   744  }
   745  
   746  func (a *CreateWalletAssertion) WithName(expected string) *CreateWalletAssertion {
   747  	assert.Equal(a.t, expected, a.resp.Wallet.Name)
   748  	return a
   749  }
   750  
   751  func (a *CreateWalletAssertion) LocatedUnder(home string) *CreateWalletAssertion {
   752  	assert.True(a.t, strings.HasPrefix(a.resp.Wallet.FilePath, home), "wallet has not been created under home directory")
   753  	return a
   754  }
   755  
   756  func WalletRename(t *testing.T, args []string) error {
   757  	t.Helper()
   758  	argsWithCmd := []string{"rename"}
   759  	argsWithCmd = append(argsWithCmd, args...)
   760  	_, err := ExecuteCmd(t, argsWithCmd)
   761  	return err
   762  }
   763  
   764  func PassphraseUpdate(t *testing.T, args []string) error {
   765  	t.Helper()
   766  	argsWithCmd := []string{"passphrase", "update"}
   767  	argsWithCmd = append(argsWithCmd, args...)
   768  	_, err := ExecuteCmd(t, argsWithCmd)
   769  	return err
   770  }
   771  
   772  type ImportWalletResponse struct {
   773  	Wallet struct {
   774  		Name                 string `json:"name"`
   775  		KeyDerivationVersion uint32 `json:"keyDerivationVersion"`
   776  		FilePath             string `json:"filePath"`
   777  	} `json:"wallet"`
   778  	Key struct {
   779  		PublicKey string `json:"publicKey"`
   780  		Algorithm struct {
   781  			Name    string `json:"name"`
   782  			Version uint32 `json:"version"`
   783  		} `json:"algorithm"`
   784  		Meta []struct {
   785  			Key   string `json:"key"`
   786  			Value string `json:"value"`
   787  		} `json:"meta"`
   788  	} `json:"key"`
   789  }
   790  
   791  func WalletImport(t *testing.T, args []string) (*ImportWalletResponse, error) {
   792  	t.Helper()
   793  	argsWithCmd := []string{"import"}
   794  	argsWithCmd = append(argsWithCmd, args...)
   795  	output, err := ExecuteCmd(t, argsWithCmd)
   796  	if err != nil {
   797  		return nil, err
   798  	}
   799  	resp := &ImportWalletResponse{}
   800  	if err := json.Unmarshal(output, resp); err != nil {
   801  		t.Fatalf("couldn't unmarshal command output: %v", err)
   802  	}
   803  	return resp, nil
   804  }
   805  
   806  type ImportWalletAssertion struct {
   807  	t    *testing.T
   808  	resp *ImportWalletResponse
   809  }
   810  
   811  func AssertImportWallet(t *testing.T, resp *ImportWalletResponse) *ImportWalletAssertion {
   812  	t.Helper()
   813  
   814  	assert.NotNil(t, resp)
   815  	assert.NotEmpty(t, resp.Wallet.Name)
   816  	assert.NotEmpty(t, resp.Wallet.KeyDerivationVersion)
   817  	assert.NotEmpty(t, resp.Wallet.FilePath)
   818  	assert.FileExists(t, resp.Wallet.FilePath)
   819  	assert.NotEmpty(t, resp.Key.PublicKey)
   820  	assert.Equal(t, "vega/ed25519", resp.Key.Algorithm.Name)
   821  	assert.Equal(t, uint32(1), resp.Key.Algorithm.Version)
   822  
   823  	return &ImportWalletAssertion{
   824  		t:    t,
   825  		resp: resp,
   826  	}
   827  }
   828  
   829  func (a *ImportWalletAssertion) WithName(expected string) *ImportWalletAssertion {
   830  	assert.Equal(a.t, expected, a.resp.Wallet.Name)
   831  	return a
   832  }
   833  
   834  func (a *ImportWalletAssertion) WithPublicKey(expected string) *ImportWalletAssertion {
   835  	assert.Equal(a.t, expected, a.resp.Key.PublicKey)
   836  	return a
   837  }
   838  
   839  func (a *ImportWalletAssertion) LocatedUnder(home string) *ImportWalletAssertion {
   840  	assert.True(a.t, strings.HasPrefix(a.resp.Wallet.FilePath, home), "wallet has not been imported under home directory")
   841  	return a
   842  }
   843  
   844  type GetWalletInfoResponse struct {
   845  	Type    string `json:"type"`
   846  	Version uint32 `json:"keyDerivationVersion"`
   847  	ID      string `json:"id"`
   848  }
   849  
   850  func WalletDescribe(t *testing.T, args []string) (*GetWalletInfoResponse, error) {
   851  	t.Helper()
   852  	argsWithCmd := []string{"describe"}
   853  	argsWithCmd = append(argsWithCmd, args...)
   854  	output, err := ExecuteCmd(t, argsWithCmd)
   855  	if err != nil {
   856  		return nil, err
   857  	}
   858  	resp := &GetWalletInfoResponse{}
   859  	if err := json.Unmarshal(output, resp); err != nil {
   860  		t.Fatalf("couldn't unmarshal command output: %v", err)
   861  	}
   862  	return resp, nil
   863  }
   864  
   865  type GetWalletInfoAssertion struct {
   866  	t    *testing.T
   867  	resp *GetWalletInfoResponse
   868  }
   869  
   870  func AssertWalletInfo(t *testing.T, resp *GetWalletInfoResponse) *GetWalletInfoAssertion {
   871  	t.Helper()
   872  
   873  	assert.NotNil(t, resp)
   874  	assert.NotEmpty(t, resp.Type)
   875  	assert.NotEmpty(t, resp.Version)
   876  	assert.NotEmpty(t, resp.ID)
   877  
   878  	return &GetWalletInfoAssertion{
   879  		t:    t,
   880  		resp: resp,
   881  	}
   882  }
   883  
   884  func (a *GetWalletInfoAssertion) IsHDWallet() *GetWalletInfoAssertion {
   885  	assert.Equal(a.t, "HD wallet", a.resp.Type)
   886  	return a
   887  }
   888  
   889  func (a *GetWalletInfoAssertion) IsIsolatedHDWallet() *GetWalletInfoAssertion {
   890  	assert.Equal(a.t, "HD wallet (isolated)", a.resp.Type)
   891  	return a
   892  }
   893  
   894  func (a *GetWalletInfoAssertion) WithLatestVersion() *GetWalletInfoAssertion {
   895  	assert.Equal(a.t, uint32(2), a.resp.Version)
   896  	return a
   897  }
   898  
   899  func (a *GetWalletInfoAssertion) WithVersion(i int) *GetWalletInfoAssertion {
   900  	assert.Equal(a.t, uint32(i), a.resp.Version)
   901  	return a
   902  }
   903  
   904  type ListWalletsResponse struct {
   905  	Wallets []string `json:"wallets"`
   906  }
   907  
   908  func WalletList(t *testing.T, args []string) (*ListWalletsResponse, error) {
   909  	t.Helper()
   910  	argsWithCmd := []string{"list"}
   911  	argsWithCmd = append(argsWithCmd, args...)
   912  	output, err := ExecuteCmd(t, argsWithCmd)
   913  	if err != nil {
   914  		return nil, err
   915  	}
   916  	resp := &ListWalletsResponse{}
   917  	if err := json.Unmarshal(output, resp); err != nil {
   918  		t.Fatalf("couldn't unmarshal command output: %v", err)
   919  	}
   920  	return resp, nil
   921  }
   922  
   923  func WalletDelete(t *testing.T, args []string) error {
   924  	t.Helper()
   925  	argsWithCmd := []string{"delete"}
   926  	argsWithCmd = append(argsWithCmd, args...)
   927  	_, err := ExecuteCmd(t, argsWithCmd)
   928  	if err != nil {
   929  		return err
   930  	}
   931  	return nil
   932  }
   933  
   934  func InitAPIToken(t *testing.T, args []string) error {
   935  	t.Helper()
   936  	argsWithCmd := []string{"api-token", "init"}
   937  	argsWithCmd = append(argsWithCmd, args...)
   938  	_, err := ExecuteCmd(t, argsWithCmd)
   939  	return err
   940  }
   941  
   942  type ListAPITokensResponse struct {
   943  	Tokens []struct {
   944  		Description string    `json:"description"`
   945  		Token       string    `json:"token"`
   946  		CreatedAt   time.Time `json:"createdAt"`
   947  	} `json:"tokens"`
   948  }
   949  
   950  func APITokensList(t *testing.T, args []string) (*ListAPITokensResponse, error) {
   951  	t.Helper()
   952  	argsWithCmd := []string{"api-token", "list"}
   953  	argsWithCmd = append(argsWithCmd, args...)
   954  	output, err := ExecuteCmd(t, argsWithCmd)
   955  	if err != nil {
   956  		return nil, err
   957  	}
   958  	resp := &ListAPITokensResponse{}
   959  	if err := json.Unmarshal(output, resp); err != nil {
   960  		t.Fatalf("couldn't unmarshal command output: %v", err)
   961  	}
   962  	return resp, nil
   963  }
   964  
   965  type APITokenGenerateResponse struct {
   966  	Token string `json:"token"`
   967  }
   968  
   969  func APITokenGenerate(t *testing.T, args []string) (*APITokenGenerateResponse, error) {
   970  	t.Helper()
   971  	argsWithCmd := []string{"api-token", "generate"}
   972  	argsWithCmd = append(argsWithCmd, args...)
   973  	output, err := ExecuteCmd(t, argsWithCmd)
   974  	if err != nil {
   975  		return nil, err
   976  	}
   977  	resp := &APITokenGenerateResponse{}
   978  	if err := json.Unmarshal(output, resp); err != nil {
   979  		t.Fatalf("couldn't unmarshal command output: %v", err)
   980  	}
   981  	return resp, nil
   982  }
   983  
   984  func AssertGenerateAPIToken(t *testing.T, resp *APITokenGenerateResponse) {
   985  	t.Helper()
   986  
   987  	assert.NotNil(t, resp)
   988  	assert.NotEmpty(t, resp.Token)
   989  }
   990  
   991  func APITokenDelete(t *testing.T, args []string) error {
   992  	t.Helper()
   993  	argsWithCmd := []string{"api-token", "delete"}
   994  	argsWithCmd = append(argsWithCmd, args...)
   995  	_, err := ExecuteCmd(t, argsWithCmd)
   996  	if err != nil {
   997  		return err
   998  	}
   999  	return nil
  1000  }