Repository: onflow/flow-cli
Pull request #431 (2021-12-22 19:50:52)

Multi key account creation
Closes #???

## Description

This PR adds the ability to specify different hashing and signature algorithms, when creating an account. This was previously not possible, and while we could add multiple keys, they all had to be uniform algorithms for both signing and hashing.

This adds the ability to specify, but also loses the defaults. With that said, do we want defaults for account creation? during the creation process, it almost feels safe to never assume, and always be explicit with the info, especially since if the account is created with the wrong algs, the account will be useless.

______

For contributor use:

- [ ] Targeted PR against `master` branch
- [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work
- [ ] Code follows the [standards mentioned here](https://github.com/onflow/flow-cli/blob/master/CONTRIBUTING.md#styleguides)
- [ ] Updated relevant documentation
- [ ] Re-reviewed `Files changed` in the Github PR explorer
- [ ] Added appropriate labels


Kay-Zee: running into issues with the integration with language server.

I guess we have to determine if this is something we do want, and if it is, will have to update the language server?

cc @sideninja
sideninja: Thank you this is great :) Regarding integration and default values, we can go either way technically, we can still provide default values if none algos are provided, but I understand your concerns with this. I think that if we use default values when generating keys we can assume those same default values when creating an account. I think this is consistent enough, however, you can make the decision yourself and just let me know so I can fix the LS accordingly. In case where we still use default values, there is no change needed in case we don't I will handle the change. If we decide to not have default values I feel we should change that in the generate keys as well. 
Also, another thing to keep in mind when changing flags is backward compatibility so here I would strongly advise to keep flags and have a warning as stated in the comment.

Patch:
diff --git a/go.mod b/go.mod
index 6926fca7..fecf301d 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/joho/godotenv v1.4.0
 	github.com/manifoldco/promptui v0.9.0
 	github.com/onflow/cadence v0.20.2
-	github.com/onflow/cadence/languageserver v0.18.3-0.20211005105715-3c618f0fcd10
+	github.com/onflow/cadence/languageserver v0.18.3-0.20220112230301-45475c847ec7
 	github.com/onflow/flow-core-contracts/lib/go/templates v0.7.9
 	github.com/onflow/flow-emulator v0.27.3
 	github.com/onflow/flow-go v0.23.4
diff --git a/go.sum b/go.sum
index 555a7fad..848038c1 100644
--- a/go.sum
+++ b/go.sum
@@ -84,6 +84,7 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
 github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
 github.com/HdrHistogram/hdrhistogram-go v0.9.0 h1:dpujRju0R4M/QZzcnR1LH1qm+TVG3UzkWdp5tH1WMcg=
 github.com/HdrHistogram/hdrhistogram-go v0.9.0/go.mod h1:nxrse8/Tzg2tg3DZcZjm6qEclQKK70g0KxO61gFFZD4=
+github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y=
 github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -631,6 +632,7 @@ github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZ
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
 github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
+github.com/ipfs/go-bitswap v0.4.0/go.mod h1:J2sAsp9UKxLgHDektSy3y3Q9OfQjM9sjhKBR1dlwrMg=
 github.com/ipfs/go-bitswap v0.5.0 h1:UTkSQpV2C2uy/bqtkFL9UOw5Da8i40qiNO24H386lek=
 github.com/ipfs/go-bitswap v0.5.0/go.mod h1:WwyyYD33RHCpczgHjpx+xjWYIy8l41K+l5EMy4/ctSM=
 github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=
@@ -668,6 +670,7 @@ github.com/ipfs/go-ds-leveldb v0.1.0/go.mod h1:hqAW8y4bwX5LWcCtku2rFNX3vjDZCy5LZ
 github.com/ipfs/go-ds-leveldb v0.4.1/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s=
 github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s=
 github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q=
+github.com/ipfs/go-ipfs-blockstore v0.1.6/go.mod h1:Jxm3XMVjh6R17WvxFEiyKBLUGr86HgIYJW/D/MwqeYQ=
 github.com/ipfs/go-ipfs-blockstore v0.2.0/go.mod h1:SNeEpz/ICnMYZQYr7KNZTjdn7tEPB/99xpe8xI1RW7o=
 github.com/ipfs/go-ipfs-blockstore v1.1.1 h1:a4koS3l+Fzl43LAAn51/N+Yn4AjCX4AGvoZLqqkrD/g=
 github.com/ipfs/go-ipfs-blockstore v1.1.1/go.mod h1:w51tNR9y5+QXB0wkNcHt4O2aSZjTdqaEWaQdSxEyUOY=
@@ -676,12 +679,16 @@ github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtL
 github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
 github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ=
 github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw=
+github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo=
+github.com/ipfs/go-ipfs-ds-help v0.1.1/go.mod h1:SbBafGJuGsPI/QL3j9Fc5YPLeAu+SzOkI0gFwAg+mOs=
 github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q=
 github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU=
+github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM=
 github.com/ipfs/go-ipfs-exchange-interface v0.1.0 h1:TiMekCrOGQuWYtZO3mf4YJXDIdNgnKWZ9IE3fGlnWfo=
 github.com/ipfs/go-ipfs-exchange-interface v0.1.0/go.mod h1:ych7WPlyHqFvCi/uQI48zLZuAWVP5iTQPXEfVaw5WEI=
 github.com/ipfs/go-ipfs-pq v0.0.2 h1:e1vOOW6MuOwG2lqxcLA+wEn93i/9laCY8sXAw76jFOY=
 github.com/ipfs/go-ipfs-pq v0.0.2/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY=
+github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY=
 github.com/ipfs/go-ipfs-routing v0.2.0 h1:EwcBZMi72MTTEuH/7a2lbXtmeO6X0COoQGWqUOGq0KU=
 github.com/ipfs/go-ipfs-routing v0.2.0/go.mod h1:384byD/LHKhAgKE3NmwOjXCpDzhczROMBzidoYV7tfM=
 github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc=
@@ -704,9 +711,11 @@ github.com/ipfs/go-log/v2 v2.3.0 h1:31Re/cPqFHpsRHgyVwjWADPoF0otB1WrjTy8ZFYwEZU=
 github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g=
 github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg=
 github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY=
+github.com/ipfs/go-peertaskqueue v0.4.0/go.mod h1:KL9F49hXJMoXCad8e5anivjN+kWdr+CyGcyh4K6doLc=
 github.com/ipfs/go-peertaskqueue v0.7.0 h1:VyO6G4sbzX80K58N60cCaHsSsypbUNs1GjO5seGNsQ0=
 github.com/ipfs/go-peertaskqueue v0.7.0/go.mod h1:M/akTIE/z1jGNXMU7kFB4TeSEFvj68ow0Rrb04donIU=
 github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8=
+github.com/ipld/go-ipld-prime v0.12.0/go.mod h1:hy8b93WleDMRKumOJnTIrr0MbbFbx9GD6Kzxa53Xppc=
 github.com/ipld/go-ipld-prime v0.14.1 h1:n9obcUnuqPK34HlfbiB+o9GhXE/x59uue4z9YTsaoj4=
 github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0=
 github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
@@ -884,6 +893,7 @@ github.com/libp2p/go-libp2p-discovery v0.3.0/go.mod h1:o03drFnz9BVAZdzC/QUQ+NeQO
 github.com/libp2p/go-libp2p-discovery v0.5.0/go.mod h1:+srtPIU9gDaBNu//UHvcdliKBIcr4SfDcm0/PfPJLug=
 github.com/libp2p/go-libp2p-discovery v0.6.0 h1:1XdPmhMJr8Tmj/yUfkJMIi8mgwWrLUsCB3bMxdT+DSo=
 github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8=
+github.com/libp2p/go-libp2p-kad-dht v0.13.0/go.mod h1:NkGf28RNhPrcsGYWJHm6EH8ULkiJ2qxsWmpE7VTL3LI=
 github.com/libp2p/go-libp2p-kad-dht v0.15.0 h1:Ke+Oj78gX5UDXnA6HBdrgvi+fStJxgYTDa51U0TsCLo=
 github.com/libp2p/go-libp2p-kad-dht v0.15.0/go.mod h1:rZtPxYu1TnHHz6n1RggdGrxUX/tA1C2/Wiw3ZMUDrU0=
 github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio=
@@ -1291,10 +1301,13 @@ github.com/onflow/cadence/languageserver v0.15.2/go.mod h1:hQGE8dYH5CfQ1Oe0nXglc
 github.com/onflow/cadence/languageserver v0.16.0/go.mod h1:UPV1so9LcMrhj27IegrTucoyS4TLRVjNr4DJqjqBhFA=
 github.com/onflow/cadence/languageserver v0.18.3-0.20211005105715-3c618f0fcd10 h1:NwuZwkATFQmdhpcymP2gYjNY6waZSS4RifKBT8HeYhA=
 github.com/onflow/cadence/languageserver v0.18.3-0.20211005105715-3c618f0fcd10/go.mod h1:kDadEzIbn14bKqIYA3yHMM1IKm2fyfOluH07Jl/SKGc=
+github.com/onflow/cadence/languageserver v0.18.3-0.20220112230301-45475c847ec7 h1:ObY2XcX9lMxohcbeC/QgzYrOvsQXaDn+VuaPAa4IW3Y=
+github.com/onflow/cadence/languageserver v0.18.3-0.20220112230301-45475c847ec7/go.mod h1:1i+YZLWlHB+UBCBGEGxcTqJ81qU1Su3GJ/9MJ+CmYYA=
 github.com/onflow/flow v0.2.3-0.20211103155021-9254a66368d5 h1:BtswF+9Qoc9QmexCTv7l9tX4YgurpXIsG5y2QIzYibw=
 github.com/onflow/flow v0.2.3-0.20211103155021-9254a66368d5/go.mod h1:lzyAYmbu1HfkZ9cfnL5/sjrrsnJiUU8fRL26CqLP7+c=
 github.com/onflow/flow-cli v0.20.3-0.20210512000809-474effb7e7db/go.mod h1:Yh4dgrNiZdXhbU+3UVUmo4gRM0TEBVvhW4ITKVo82dg=
 github.com/onflow/flow-cli v0.23.1-0.20210621124332-11c4cd22ffb4/go.mod h1:OD9UVPFIvktnO86dSLavf1tTVFIsKQ5By5KBBDLfC3Q=
+github.com/onflow/flow-cli v0.29.0/go.mod h1:slJqAWVVwwOtpJh65Bxtn5E3LslMmKD950YbV0sBues=
 github.com/onflow/flow-core-contracts/lib/go/contracts v0.7.2/go.mod h1:IZ2e7UyLCYmpQ8Kd7k0A32uXqdqfiV1r2sKs5/riblo=
 github.com/onflow/flow-core-contracts/lib/go/contracts v0.7.3-0.20210527134022-58c25247091a/go.mod h1:IZ2e7UyLCYmpQ8Kd7k0A32uXqdqfiV1r2sKs5/riblo=
 github.com/onflow/flow-core-contracts/lib/go/contracts v0.7.3/go.mod h1:MSNt2rodpRXm1n0iGQWL6ltDoJCtXEzlPw9nhE/zQmk=
@@ -1307,6 +1320,7 @@ github.com/onflow/flow-core-contracts/lib/go/templates v0.7.9/go.mod h1:ckE1lQ18
 github.com/onflow/flow-emulator v0.19.0/go.mod h1:k5un51XlFJavboagCqTxd6x8Gle7lxWlXdUepoNB5fA=
 github.com/onflow/flow-emulator v0.20.3/go.mod h1:xNdVsrMJiAaYJ59Dwo+xvj0ENdvk/bI14zkGN4V0ozs=
 github.com/onflow/flow-emulator v0.21.0/go.mod h1:/2dNG6K4fKtpZsazdIeK8Fs0IWXUzqvO3qK5467pYsc=
+github.com/onflow/flow-emulator v0.26.0/go.mod h1:7kQjbpuejgPTWNFzLM9/TXwg+3x172VyesFZc1achak=
 github.com/onflow/flow-emulator v0.27.3 h1:00e1EO504owU7XKFbBRaWR6tarXIZnrr0WQy0riLBws=
 github.com/onflow/flow-emulator v0.27.3/go.mod h1:oL8MvN6UC2GRj4dJdag9DbuoCF5tt1S+kL7QvhmetLA=
 github.com/onflow/flow-ft/lib/go/contracts v0.5.0 h1:Cg4gHGVblxcejfNNG5Mfj98Wf4zbY76O0Y28QB0766A=
@@ -1315,6 +1329,7 @@ github.com/onflow/flow-go v0.16.3-0.20210427194927-6050c2a3ae42/go.mod h1:9GUEbB
 github.com/onflow/flow-go v0.17.1/go.mod h1:j8zCo01+2pJL00qpOnwdOqU7spTgOLHFRUp9gsamyNA=
 github.com/onflow/flow-go v0.18.0/go.mod h1:cQpvFoqth9PR7tarWDa36R/dDOqUK5QYfeYzCdXPLII=
 github.com/onflow/flow-go v0.18.2-canary/go.mod h1:mGzTPbzG1YrckrFQfjCw6NzfflP1o3TjRxI9LRWZbpc=
+github.com/onflow/flow-go v0.23.2-0.20211125195119-1ee2fc2dd5d9/go.mod h1:ydmBvXy06/Bkwt6jlxZ+Pu8MrJPjq5OEAp8O34N/te4=
 github.com/onflow/flow-go v0.23.4 h1:YIrfXb+1pFYwAO4z1soPbw0WRcQtStu8Vc5i1G/4soE=
 github.com/onflow/flow-go v0.23.4/go.mod h1:b9kXGcTjCFveFRYi0SRCWmDC2WAUHvkno6Pqpa8yrCk=
 github.com/onflow/flow-go-sdk v0.18.0/go.mod h1:AjXHdxguP/PK5P8tWKHH4jR6oLISTgLoXXQrbQsHY+E=
diff --git a/internal/accounts/create.go b/internal/accounts/create.go
index e1148bb8..3f7d2af9 100644
--- a/internal/accounts/create.go
+++ b/internal/accounts/create.go
@@ -36,8 +36,8 @@ type flagsCreate struct {
 	Signer    string   `default:"emulator-account" flag:"signer" info:"Account name from configuration used to sign the transaction"`
 	Keys      []string `flag:"key" info:"Public keys to attach to account"`
 	Weights   []int    `flag:"key-weight" info:"Weight for the key"`
-	SigAlgo   string   `default:"ECDSA_P256" flag:"sig-algo" info:"Signature algorithm used to generate the keys"`
-	HashAlgo  string   `default:"SHA3_256" flag:"hash-algo" info:"Hash used for the digest"`
+	SigAlgo   []string `default:"ECDSA_P256" flag:"sig-algo" info:"Signature algorithm used to generate the keys"`
+	HashAlgo  []string `default:"SHA3_256" flag:"hash-algo" info:"Hash used for the digest"`
 	Contracts []string `flag:"contract" info:"Contract to be deployed during account creation. <name:filename>"`
 	Include   []string `default:"" flag:"include" info:"Fields to include in the output"`
 }
@@ -66,23 +66,50 @@ func create(
 		return nil, err
 	}
 
-	sigAlgo := crypto.StringToSignatureAlgorithm(createFlags.SigAlgo)
-	if sigAlgo == crypto.UnknownSignatureAlgorithm {
-		return nil, fmt.Errorf("invalid signature algorithm: %s", createFlags.SigAlgo)
+	if len(createFlags.SigAlgo) == 1 && len(createFlags.HashAlgo) == 1 {
+		// Fill up depending on size of key input
+		if len(createFlags.Keys) > 1 {
+			for i := 1; i < len(createFlags.Keys); i++ {
+				createFlags.SigAlgo = append(createFlags.SigAlgo, createFlags.SigAlgo[0])
+				createFlags.HashAlgo = append(createFlags.HashAlgo, createFlags.HashAlgo[0])
+			}
+			// Deprecated usage message?
+		}
+
+	} else
+	// double check matching array lengths on inputs
+	if len(createFlags.Keys) != len(createFlags.SigAlgo) || len(createFlags.SigAlgo) != len(createFlags.HashAlgo) {
+		return nil, fmt.Errorf("must provide a signature and hash algorithm for every key provided to --key: %d keys, %d signature algo, %d hash algo", len(createFlags.Keys), len(createFlags.SigAlgo), len(createFlags.HashAlgo))
 	}
 
-	hashAlgo := crypto.StringToHashAlgorithm(createFlags.HashAlgo)
-	if hashAlgo == crypto.UnknownHashAlgorithm {
-		return nil, fmt.Errorf("invalid hash algorithm: %s", createFlags.HashAlgo)
+	// read all signature algorithms
+	sigAlgos := make([]crypto.SignatureAlgorithm, 0, len(createFlags.SigAlgo))
+	for _, sigAlgoStr := range createFlags.SigAlgo {
+		sigAlgo := crypto.StringToSignatureAlgorithm(sigAlgoStr)
+		if sigAlgo == crypto.UnknownSignatureAlgorithm {
+			return nil, fmt.Errorf("invalid signature algorithm: %s", createFlags.SigAlgo)
+		}
+		sigAlgos = append(sigAlgos, sigAlgo)
+	}
+
+	// read all hash algorithms
+	hashAlgos := make([]crypto.HashAlgorithm, 0, len(createFlags.HashAlgo))
+	for _, hashAlgoStr := range createFlags.HashAlgo {
+
+		hashAlgo := crypto.StringToHashAlgorithm(hashAlgoStr)
+		if hashAlgo == crypto.UnknownHashAlgorithm {
+			return nil, fmt.Errorf("invalid hash algorithm: %s", createFlags.HashAlgo)
+		}
+		hashAlgos = append(hashAlgos, hashAlgo)
 	}
 
 	keyWeights := createFlags.Weights
 
 	// decode public keys
-	var pubKeys []crypto.PublicKey
-	for _, k := range createFlags.Keys {
+	pubKeys := make([]crypto.PublicKey, 0, len(createFlags.Keys))
+	for i, k := range createFlags.Keys {
 		k = strings.TrimPrefix(k, "0x") // clear possible prefix
-		key, err := crypto.DecodePublicKeyHex(sigAlgo, k)
+		key, err := crypto.DecodePublicKeyHex(sigAlgos[i], k)
 		if err != nil {
 			return nil, fmt.Errorf("failed decoding public key: %s with error: %w", key, err)
 		}
@@ -93,8 +120,8 @@ func create(
 		signer,
 		pubKeys,
 		keyWeights,
-		sigAlgo,
-		hashAlgo,
+		sigAlgos,
+		hashAlgos,
 		createFlags.Contracts,
 	)
 
diff --git a/pkg/flowkit/services/accounts.go b/pkg/flowkit/services/accounts.go
index e1cee952..6bf6c008 100644
--- a/pkg/flowkit/services/accounts.go
+++ b/pkg/flowkit/services/accounts.go
@@ -114,8 +114,8 @@ func (a *Accounts) Create(
 	signer *flowkit.Account,
 	pubKeys []crypto.PublicKey,
 	keyWeights []int,
-	sigAlgo crypto.SignatureAlgorithm,
-	hashAlgo crypto.HashAlgorithm,
+	sigAlgo []crypto.SignatureAlgorithm,
+	hashAlgo []crypto.HashAlgorithm,
 	contractArgs []string,
 ) (*flow.Account, error) {
 	if a.state == nil {
@@ -140,8 +140,8 @@ func (a *Accounts) Create(
 
 		accKey := &flow.AccountKey{
 			PublicKey: pubKey,
-			SigAlgo:   sigAlgo,
-			HashAlgo:  hashAlgo,
+			SigAlgo:   sigAlgo[i],
+			HashAlgo:  hashAlgo[i],
 			Weight:    weight,
 		}
 


Test patch:
diff --git a/pkg/flowkit/services/accounts_test.go b/pkg/flowkit/services/accounts_test.go
index a2306c83..642b2a00 100644
--- a/pkg/flowkit/services/accounts_test.go
+++ b/pkg/flowkit/services/accounts_test.go
@@ -98,8 +98,8 @@ func TestAccounts(t *testing.T) {
 			serviceAcc,
 			[]crypto.PublicKey{pubKey},
 			[]int{1000},
-			crypto.ECDSA_P256,
-			crypto.SHA3_256,
+			[]crypto.SignatureAlgorithm{crypto.ECDSA_P256},
+			[]crypto.HashAlgorithm{crypto.SHA3_256},
 			nil,
 		)
 
@@ -134,8 +134,8 @@ func TestAccounts(t *testing.T) {
 			serviceAcc,
 			[]crypto.PublicKey{pubKey},
 			[]int{1000},
-			crypto.ECDSA_P256,
-			crypto.SHA3_256,
+			[]crypto.SignatureAlgorithm{crypto.ECDSA_P256},
+			[]crypto.HashAlgorithm{crypto.SHA3_256},
 			[]string{"Hello:contractHello.cdc"},
 		)
 
@@ -259,8 +259,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 		account  *flowkit.Account
 		pubKeys  []crypto.PublicKey
 		weights  []int
-		sigAlgo  crypto.SignatureAlgorithm
-		hashAlgo crypto.HashAlgorithm
+		sigAlgo  []crypto.SignatureAlgorithm
+		hashAlgo []crypto.HashAlgorithm
 		args     []string
 	}
 
@@ -279,19 +279,29 @@ func TestAccountsCreate_Integration(t *testing.T) {
 		srvAcc, _ := state.EmulatorServiceAccount()
 
 		accIn := []accountsIn{{
-			account:  srvAcc,
-			sigAlgo:  crypto.ECDSA_P256,
-			hashAlgo: crypto.SHA3_256,
-			args:     nil,
+			account: srvAcc,
+			sigAlgo: []crypto.SignatureAlgorithm{
+				tests.SigAlgos()[0],
+			},
+			hashAlgo: []crypto.HashAlgorithm{
+				tests.HashAlgos()[0],
+			},
+			args: nil,
 			pubKeys: []crypto.PublicKey{
 				tests.PubKeys()[0],
 			},
 			weights: []int{flow.AccountKeyWeightThreshold},
 		}, {
-			account:  srvAcc,
-			args:     nil,
-			sigAlgo:  crypto.ECDSA_P256,
-			hashAlgo: crypto.SHA3_256,
+			account: srvAcc,
+			args:    nil,
+			sigAlgo: []crypto.SignatureAlgorithm{
+				tests.SigAlgos()[0],
+				tests.SigAlgos()[1],
+			},
+			hashAlgo: []crypto.HashAlgorithm{
+				tests.HashAlgos()[0],
+				tests.HashAlgos()[1],
+			},
 			pubKeys: []crypto.PublicKey{
 				tests.PubKeys()[0],
 				tests.PubKeys()[1],
@@ -305,8 +315,12 @@ func TestAccountsCreate_Integration(t *testing.T) {
 					tests.ContractSimple.Filename,
 				),
 			},
-			sigAlgo:  crypto.ECDSA_P256,
-			hashAlgo: crypto.SHA3_256,
+			sigAlgo: []crypto.SignatureAlgorithm{
+				tests.SigAlgos()[0],
+			},
+			hashAlgo: []crypto.HashAlgorithm{
+				tests.HashAlgos()[0],
+			},
 			pubKeys: []crypto.PublicKey{
 				tests.PubKeys()[0],
 			},
@@ -356,8 +370,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 			for x, k := range acc.Keys {
 				assert.Equal(t, k.PublicKey, a.pubKeys[x])
 				assert.Equal(t, k.Weight, c.weights[x])
-				assert.Equal(t, k.SigAlgo, a.sigAlgo)
-				assert.Equal(t, k.HashAlgo, a.hashAlgo)
+				assert.Equal(t, k.SigAlgo, a.sigAlgo[x])
+				assert.Equal(t, k.HashAlgo, a.hashAlgo[x])
 			}
 
 		}
@@ -381,8 +395,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 		accIn := []accountsIn{
 			{
 				account:  srvAcc,
-				sigAlgo:  crypto.ECDSA_P256,
-				hashAlgo: crypto.SHA3_256,
+				sigAlgo:  []crypto.SignatureAlgorithm{crypto.ECDSA_P256},
+				hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
 				args:     []string{"Invalid:Invalid"},
 				pubKeys: []crypto.PublicKey{
 					tests.PubKeys()[0],
@@ -390,8 +404,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 				weights: []int{1000},
 			}, {
 				account:  srvAcc,
-				sigAlgo:  crypto.UnknownSignatureAlgorithm,
-				hashAlgo: crypto.SHA3_256,
+				sigAlgo:  []crypto.SignatureAlgorithm{crypto.UnknownSignatureAlgorithm},
+				hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
 				args:     nil,
 				pubKeys: []crypto.PublicKey{
 					tests.PubKeys()[0],
@@ -399,8 +413,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 				weights: []int{1000},
 			}, {
 				account:  srvAcc,
-				sigAlgo:  crypto.UnknownSignatureAlgorithm,
-				hashAlgo: crypto.UnknownHashAlgorithm,
+				sigAlgo:  []crypto.SignatureAlgorithm{crypto.UnknownSignatureAlgorithm},
+				hashAlgo: []crypto.HashAlgorithm{crypto.UnknownHashAlgorithm},
 				args:     nil,
 				pubKeys: []crypto.PublicKey{
 					tests.PubKeys()[0],
@@ -408,8 +422,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 				weights: []int{1000},
 			}, {
 				account:  srvAcc,
-				sigAlgo:  crypto.ECDSA_P256,
-				hashAlgo: crypto.SHA3_256,
+				sigAlgo:  []crypto.SignatureAlgorithm{crypto.ECDSA_P256},
+				hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
 				args:     nil,
 				pubKeys: []crypto.PublicKey{
 					tests.PubKeys()[0],
@@ -418,8 +432,8 @@ func TestAccountsCreate_Integration(t *testing.T) {
 				weights: []int{1000},
 			}, {
 				account:  srvAcc,
-				sigAlgo:  crypto.ECDSA_P256,
-				hashAlgo: crypto.SHA3_256,
+				sigAlgo:  []crypto.SignatureAlgorithm{crypto.ECDSA_P256},
+				hashAlgo: []crypto.HashAlgorithm{crypto.SHA3_256},
 				args:     nil,
 				pubKeys: []crypto.PublicKey{
 					tests.PubKeys()[0],
diff --git a/pkg/flowkit/services/blocks_test.go b/pkg/flowkit/services/blocks_test.go
index e84b6c4a..f7eb6bc1 100644
--- a/pkg/flowkit/services/blocks_test.go
+++ b/pkg/flowkit/services/blocks_test.go
@@ -22,7 +22,6 @@ import (
 	"testing"
 
 	"github.com/onflow/flow-go-sdk"
-	"github.com/onflow/flow-go-sdk/crypto"
 	"github.com/stretchr/testify/assert"
 
 	"github.com/onflow/flow-cli/tests"
@@ -108,7 +107,7 @@ func TestBlocksGet_Integration(t *testing.T) {
 		assert.Equal(t, block.ID.String(), "7bc42fe85d32ca513769a74f97f7e1a7bad6c9407f0d934c2aa645ef9cf613c7")
 
 		// create an event
-		_, _ = s.Accounts.Create(srvAcc, tests.PubKeys(), nil, crypto.ECDSA_P256, crypto.SHA3_256, nil)
+		_, _ = s.Accounts.Create(srvAcc, tests.PubKeys(), nil, tests.SigAlgos(), tests.HashAlgos(), nil)
 
 		block, blockEvents, _, err = s.Blocks.GetBlock("latest", "flow.AccountCreated", true)
 
diff --git a/pkg/flowkit/services/transactions_test.go b/pkg/flowkit/services/transactions_test.go
index 776a9f60..21e99793 100644
--- a/pkg/flowkit/services/transactions_test.go
+++ b/pkg/flowkit/services/transactions_test.go
@@ -111,8 +111,8 @@ func setupAccount(state *flowkit.State, s *Services, account *flowkit.Account) {
 	acc, _ := s.Accounts.Create(srv,
 		[]crypto.PublicKey{(*pk).PublicKey()},
 		[]int{flow.AccountKeyWeightThreshold},
-		key.SigAlgo(),
-		key.HashAlgo(),
+		[]crypto.SignatureAlgorithm{key.SigAlgo()},
+		[]crypto.HashAlgorithm{key.HashAlgo()},
 		nil,
 	)
 
diff --git a/tests/resources.go b/tests/resources.go
index d432d092..b5074a00 100644
--- a/tests/resources.go
+++ b/tests/resources.go
@@ -277,12 +277,9 @@ func newAccount(name string, address string, seed string) *flowkit.Account {
 
 func PubKeys() []crypto.PublicKey {
 	var pubKeys []crypto.PublicKey
-	for x := 0; x < 5; x++ {
-		pk, _ := crypto.GeneratePrivateKey(
-			crypto.ECDSA_P256,
-			[]byte(fmt.Sprintf("seedseedseedseedseedseedseedseedseedseedseedseed%d", x)),
-		)
-		pubKeys = append(pubKeys, pk.PublicKey())
+	privKeys := PrivKeys()
+	for _, priv := range privKeys {
+		pubKeys = append(pubKeys, priv.PublicKey())
 	}
 	return pubKeys
 }
@@ -298,3 +295,20 @@ func PrivKeys() []crypto.PrivateKey {
 	}
 	return privKeys
 }
+
+func SigAlgos() []crypto.SignatureAlgorithm {
+	var sigAlgos []crypto.SignatureAlgorithm
+	privKeys := PrivKeys()
+	for _, priv := range privKeys {
+		sigAlgos = append(sigAlgos, priv.Algorithm())
+	}
+	return sigAlgos
+}
+
+func HashAlgos() []crypto.HashAlgorithm {
+	var hashAlgos []crypto.HashAlgorithm
+	for x := 0; x < 5; x++ {
+		hashAlgos = append(hashAlgos, crypto.SHA3_256)
+	}
+	return hashAlgos
+}