github.com/hyperledger/aries-framework-go@v0.3.2/pkg/client/didconfig/didconfig_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package didconfig
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/json"
    12  	"fmt"
    13  	"io"
    14  	"net/http"
    15  	"net/http/httptest"
    16  	"testing"
    17  
    18  	"github.com/stretchr/testify/require"
    19  
    20  	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
    21  	"github.com/hyperledger/aries-framework-go/pkg/doc/ldcontext"
    22  	"github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
    23  	"github.com/hyperledger/aries-framework-go/pkg/vdr"
    24  	"github.com/hyperledger/aries-framework-go/pkg/vdr/httpbinding"
    25  	"github.com/hyperledger/aries-framework-go/pkg/vdr/key"
    26  )
    27  
    28  const (
    29  	testDID    = "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM"
    30  	testDomain = "https://identity.foundation"
    31  
    32  	contextV1 = "https://identity.foundation/.well-known/did-configuration/v1"
    33  )
    34  
    35  func TestNew(t *testing.T) {
    36  	t.Run("success - default options", func(t *testing.T) {
    37  		c := New()
    38  		require.NotNil(t, c)
    39  		require.Len(t, c.didConfigOpts, 0)
    40  	})
    41  
    42  	t.Run("success - did config options provided", func(t *testing.T) {
    43  		loader, err := ldtestutil.DocumentLoader(ldcontext.Document{
    44  			URL:     contextV1,
    45  			Content: json.RawMessage(didCfgCtxV1),
    46  		})
    47  		require.NoError(t, err)
    48  
    49  		c := New(WithJSONLDDocumentLoader(loader),
    50  			WithVDRegistry(vdr.New(vdr.WithVDR(key.New()))),
    51  			WithHTTPClient(&http.Client{}))
    52  		require.NotNil(t, c)
    53  		require.Len(t, c.didConfigOpts, 2)
    54  	})
    55  }
    56  
    57  func TestVerifyDIDAndDomain(t *testing.T) {
    58  	loader, err := ldtestutil.DocumentLoader(ldcontext.Document{
    59  		URL:     contextV1,
    60  		Content: json.RawMessage(didCfgCtxV1),
    61  	})
    62  	require.NoError(t, err)
    63  
    64  	t.Run("success", func(t *testing.T) {
    65  		httpClient := &mockHTTPClient{
    66  			DoFunc: func(req *http.Request) (*http.Response, error) {
    67  				return &http.Response{
    68  					StatusCode: http.StatusOK,
    69  					Body:       io.NopCloser(bytes.NewReader([]byte(didCfg))),
    70  				}, nil
    71  			},
    72  		}
    73  
    74  		c := New(WithJSONLDDocumentLoader(loader), WithHTTPClient(httpClient))
    75  
    76  		err := c.VerifyDIDAndDomain(testDID, testDomain)
    77  		require.NoError(t, err)
    78  	})
    79  
    80  	t.Run("success", func(t *testing.T) {
    81  		httpClient := &mockHTTPClient{
    82  			DoFunc: func(req *http.Request) (*http.Response, error) {
    83  				return &http.Response{
    84  					StatusCode: http.StatusOK,
    85  					Body:       io.NopCloser(bytes.NewReader([]byte(didCfg))),
    86  				}, nil
    87  			},
    88  		}
    89  
    90  		c := New(WithJSONLDDocumentLoader(loader), WithHTTPClient(httpClient))
    91  
    92  		err := c.VerifyDIDAndDomain(testDID, testDomain)
    93  		require.NoError(t, err)
    94  	})
    95  
    96  	t.Run("error - http client error", func(t *testing.T) {
    97  		c := New(WithJSONLDDocumentLoader(loader))
    98  
    99  		err := c.VerifyDIDAndDomain(testDID, "https://non-existent-abc.com")
   100  		require.Error(t, err)
   101  		require.Contains(t, err.Error(),
   102  			"Get \"https://non-existent-abc.com/.well-known/did-configuration.json\": dial tcp: "+
   103  				"lookup non-existent-abc.com: no such host")
   104  	})
   105  
   106  	t.Run("error - http request error", func(t *testing.T) {
   107  		c := New(WithJSONLDDocumentLoader(loader))
   108  
   109  		err := c.VerifyDIDAndDomain(testDID, ":invalid.com")
   110  		require.Error(t, err)
   111  		require.Contains(t, err.Error(), "missing protocol scheme")
   112  	})
   113  
   114  	t.Run("error - http status error", func(t *testing.T) {
   115  		httpClient := &mockHTTPClient{
   116  			DoFunc: func(req *http.Request) (*http.Response, error) {
   117  				return &http.Response{
   118  					StatusCode: http.StatusNotFound,
   119  					Body:       io.NopCloser(bytes.NewReader([]byte("data not found"))),
   120  				}, nil
   121  			},
   122  		}
   123  
   124  		c := New(WithJSONLDDocumentLoader(loader), WithHTTPClient(httpClient))
   125  
   126  		err := c.VerifyDIDAndDomain(testDID, testDomain)
   127  		require.Error(t, err)
   128  		require.Contains(t, err.Error(), "endpoint https://identity.foundation/.well-known/did-configuration.json "+
   129  			"returned status '404' and message 'data not found'")
   130  	})
   131  
   132  	t.Run("error - did configuration missing linked DIDs", func(t *testing.T) {
   133  		httpClient := &mockHTTPClient{
   134  			DoFunc: func(req *http.Request) (*http.Response, error) {
   135  				return &http.Response{
   136  					StatusCode: http.StatusOK,
   137  					Body:       io.NopCloser(bytes.NewReader([]byte(didCfgNoLinkedDIDs))),
   138  				}, nil
   139  			},
   140  		}
   141  
   142  		c := New(WithJSONLDDocumentLoader(loader),
   143  			WithVDRegistry(vdr.New(vdr.WithVDR(key.New()))),
   144  			WithHTTPClient(httpClient))
   145  
   146  		err := c.VerifyDIDAndDomain(testDID, testDomain)
   147  		require.Error(t, err)
   148  		require.Contains(t, err.Error(), "did configuration: property 'linked_dids' is required ")
   149  	})
   150  }
   151  
   152  func TestCloseResponseBody(t *testing.T) {
   153  	t.Run("error", func(t *testing.T) {
   154  		closeResponseBody(&mockCloser{Err: fmt.Errorf("test error")})
   155  	})
   156  }
   157  
   158  type mockHTTPClient struct {
   159  	DoFunc func(req *http.Request) (*http.Response, error)
   160  }
   161  
   162  func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
   163  	return m.DoFunc(req)
   164  }
   165  
   166  type mockCloser struct {
   167  	Err error
   168  }
   169  
   170  func (c *mockCloser) Close() error {
   171  	return c.Err
   172  }
   173  
   174  // nolint: lll
   175  const didCfg = `
   176  {
   177    "@context": "https://identity.foundation/.well-known/did-configuration/v1",
   178    "linked_dids": [
   179      {
   180        "@context": [
   181          "https://www.w3.org/2018/credentials/v1",
   182          "https://identity.foundation/.well-known/did-configuration/v1"
   183        ],
   184        "issuer": "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM",
   185        "issuanceDate": "2020-12-04T14:08:28-06:00",
   186        "expirationDate": "2025-12-04T14:08:28-06:00",
   187        "type": [
   188          "VerifiableCredential",
   189          "DomainLinkageCredential"
   190        ],
   191        "credentialSubject": {
   192          "id": "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM",
   193          "origin": "https://identity.foundation"
   194        },
   195        "proof": {
   196          "type": "Ed25519Signature2018",
   197          "created": "2020-12-04T20:08:28.540Z",
   198          "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..D0eDhglCMEjxDV9f_SNxsuU-r3ZB9GR4vaM9TYbyV7yzs1WfdUyYO8rFZdedHbwQafYy8YOpJ1iJlkSmB4JaDQ",
   199          "proofPurpose": "assertionMethod",
   200          "verificationMethod": "did:key:z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM#z6MkoTHsgNNrby8JzCNQ1iRLyW5QQ6R8Xuu6AA8igGrMVPUM"
   201        }
   202      }
   203    ]
   204  }`
   205  
   206  const didCfgNoLinkedDIDs = `
   207  {
   208    "@context": "https://identity.foundation/.well-known/did-configuration/v1"
   209  }`
   210  
   211  // nolint: lll
   212  const didCfgCtxV1 = `
   213  {
   214    "@context": [
   215      {
   216        "@version": 1.1,
   217        "@protected": true,
   218        "LinkedDomains": "https://identity.foundation/.well-known/resources/did-configuration/#LinkedDomains",
   219        "DomainLinkageCredential": "https://identity.foundation/.well-known/resources/did-configuration/#DomainLinkageCredential",
   220        "origin": "https://identity.foundation/.well-known/resources/did-configuration/#origin",
   221        "linked_dids": "https://identity.foundation/.well-known/resources/did-configuration/#linked_dids"
   222      }
   223    ]
   224  }`
   225  
   226  func TestInterop(t *testing.T) {
   227  	const contextV0 = "https://identity.foundation/.well-known/contexts/did-configuration-v0.0.jsonld"
   228  
   229  	const contextV1 = "https://identity.foundation/.well-known/did-configuration/v1"
   230  
   231  	loader, err := ldtestutil.DocumentLoader(
   232  		ldcontext.Document{
   233  			URL:     contextV1,
   234  			Content: json.RawMessage(didCfgCtxV1),
   235  		},
   236  		ldcontext.Document{
   237  			URL:     contextV0,
   238  			Content: json.RawMessage(didCfgCtxV0),
   239  		},
   240  	)
   241  	require.NoError(t, err)
   242  
   243  	httpClient := &mockHTTPClient{
   244  		DoFunc: func(req *http.Request) (*http.Response, error) {
   245  			return &http.Response{
   246  				StatusCode: http.StatusOK,
   247  				Body:       io.NopCloser(bytes.NewReader([]byte(msCfg))),
   248  			}, nil
   249  		},
   250  	}
   251  
   252  	t.Run("success - MS interop", func(t *testing.T) {
   253  		testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
   254  			require.Equal(t, "/"+msDID, req.URL.String())
   255  			res.Header().Add("Content-type", "application/did+ld+json")
   256  			res.WriteHeader(http.StatusOK)
   257  			_, err := res.Write([]byte(msResolutionResponse))
   258  			require.NoError(t, err)
   259  		}))
   260  
   261  		defer func() { testServer.Close() }()
   262  
   263  		resolver, err := httpbinding.New(testServer.URL)
   264  		require.NoError(t, err)
   265  
   266  		gotDocument, err := resolver.Read(msDID)
   267  		require.NoError(t, err)
   268  		didDoc, err := did.ParseDocument([]byte(msDoc))
   269  		require.NoError(t, err)
   270  		require.Equal(t, didDoc.ID, gotDocument.DIDDocument.ID)
   271  
   272  		c := New(WithJSONLDDocumentLoader(loader), WithHTTPClient(httpClient), WithVDRegistry(vdr.New(vdr.WithVDR(resolver))))
   273  
   274  		err = c.VerifyDIDAndDomain(msDID, msDomain)
   275  		require.NoError(t, err)
   276  	})
   277  }
   278  
   279  // ms constants.
   280  const (
   281  	// nolint: lll
   282  	msDID    = "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiI2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJqNVQ4S1FfQ19IRGxSbXlFX1pwRjltbE1RZ3B4N19fMFJQRHhPVmM4dWt3IiwieSI6InpybDBWSllHWnhVLXFjZWt2SlY4NGs5U2x2STQxam53NG4yTS1WMnB4MGMifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJhc3NlcnRpb25NZXRob2QiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoibGlua2VkZG9tYWlucyIsInNlcnZpY2VFbmRwb2ludCI6eyJvcmlnaW5zIjpbImh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8iXX0sInR5cGUiOiJMaW5rZWREb21haW5zIn0seyJpZCI6Imh1YiIsInNlcnZpY2VFbmRwb2ludCI6eyJpbnN0YW5jZXMiOlsiaHR0cHM6Ly9iZXRhLmh1Yi5tc2lkZW50aXR5LmNvbS92MS4wL2E0OTJjZmYyLWQ3MzMtNDA1Ny05NWE1LWE3MWZjMzY5NWJjOCJdfSwidHlwZSI6IklkZW50aXR5SHViIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlDcXRpZnUwSHg4RUVkbGlrVnZIWGpYZzRLb0pZZUV0cDdZeGlvRzVYWmRKZyJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpQ1NVQklmYTBXZHBXNm5oVTdNaHlSczRucTFDeEg1V1ZyUjVkUFZYV09MYmciLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUF1cGoxRWZsOHdjWlRQZTI3X0lGWEJ3MjlzOEN5SXBRX3UzVkRwUmswdkNRIn19"
   283  	msDomain = "https://did.rohitgulati.com/"
   284  
   285  	didCfgCtxV0 = `
   286  {
   287    "@context": [
   288      {
   289        "@version": 1.1,
   290        "didcfg": "https://identity.foundation/.well-known/contexts/did-configuration-v0.0#",
   291        "domainLinkageAssertion": "didcfg:domainLinkageAssertion",
   292        "origin": "didcfg:origin",
   293        "linked_dids": "didcfg:linked_dids",
   294        "did": "didcfg:did",
   295        "vc": "didcfg:vc"
   296      }
   297    ]
   298  }`
   299  
   300  	// source: https://did.rohitgulati.com/.well-known/did-configuration.json
   301  	// nolint: lll
   302  	msCfg = `
   303  {
   304    "@context": "https://identity.foundation/.well-known/contexts/did-configuration-v0.0.jsonld",
   305    "linked_dids": [
   306      "eyJhbGciOiJFUzI1NksiLCJraWQiOiJkaWQ6aW9uOkVpQ01kVkx0enFxVzVuNnpVQzNfc3JaeFdQQ3NlVnhLWHU5RnFROEx5UzFtVEE6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSnlaWEJzWVdObElpd2laRzlqZFcxbGJuUWlPbnNpY0hWaWJHbGpTMlY1Y3lJNlczc2lhV1FpT2lJMk5tUmtOVEZtWlRCallXTTBaakZoWVdVNE1USmtNR0ZoTVRBNVltTXlZWFpqVTJsbmJtbHVaMHRsZVMweVpUazNOU0lzSW5CMVlteHBZMHRsZVVwM2F5STZleUpqY25ZaU9pSnpaV053TWpVMmF6RWlMQ0pyZEhraU9pSkZReUlzSW5naU9pSnFOVlE0UzFGZlExOUlSR3hTYlhsRlgxcHdSamx0YkUxUlozQjROMTlmTUZKUVJIaFBWbU00ZFd0M0lpd2llU0k2SW5weWJEQldTbGxIV25oVkxYRmpaV3QyU2xZNE5HczVVMngyU1RReGFtNTNORzR5VFMxV01uQjRNR01pZlN3aWNIVnljRzl6WlhNaU9sc2lZWFYwYUdWdWRHbGpZWFJwYjI0aUxDSmhjM05sY25ScGIyNU5aWFJvYjJRaVhTd2lkSGx3WlNJNklrVmpaSE5oVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T1NKOVhTd2ljMlZ5ZG1salpYTWlPbHQ3SW1sa0lqb2liR2x1YTJWa1pHOXRZV2x1Y3lJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnZjbWxuYVc1eklqcGJJbWgwZEhCek9pOHZaR2xrTG5KdmFHbDBaM1ZzWVhScExtTnZiUzhpWFgwc0luUjVjR1VpT2lKTWFXNXJaV1JFYjIxaGFXNXpJbjBzZXlKcFpDSTZJbWgxWWlJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnBibk4wWVc1alpYTWlPbHNpYUhSMGNITTZMeTlpWlhSaExtaDFZaTV0YzJsa1pXNTBhWFI1TG1OdmJTOTJNUzR3TDJFME9USmpabVl5TFdRM016TXROREExTnkwNU5XRTFMV0UzTVdaak16WTVOV0pqT0NKZGZTd2lkSGx3WlNJNklrbGtaVzUwYVhSNVNIVmlJbjFkZlgxZExDSjFjR1JoZEdWRGIyMXRhWFJ0Wlc1MElqb2lSV2xEY1hScFpuVXdTSGc0UlVWa2JHbHJWblpJV0dwWVp6UkxiMHBaWlVWMGNEZFplR2x2UnpWWVdtUktaeUo5TENKemRXWm1hWGhFWVhSaElqcDdJbVJsYkhSaFNHRnphQ0k2SWtWcFExTlZRa2xtWVRCWFpIQlhObTVvVlRkTmFIbFNjelJ1Y1RGRGVFZzFWMVp5VWpWa1VGWllWMDlNWW1jaUxDSnlaV052ZG1WeWVVTnZiVzFwZEcxbGJuUWlPaUpGYVVGMWNHb3hSV1pzT0hkaldsUlFaVEkzWDBsR1dFSjNNamx6T0VONVNYQlJYM1V6VmtSd1Vtc3dka05SSW4xOSM2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSJ9.eyJzdWIiOiJkaWQ6aW9uOkVpQ01kVkx0enFxVzVuNnpVQzNfc3JaeFdQQ3NlVnhLWHU5RnFROEx5UzFtVEE6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSnlaWEJzWVdObElpd2laRzlqZFcxbGJuUWlPbnNpY0hWaWJHbGpTMlY1Y3lJNlczc2lhV1FpT2lJMk5tUmtOVEZtWlRCallXTTBaakZoWVdVNE1USmtNR0ZoTVRBNVltTXlZWFpqVTJsbmJtbHVaMHRsZVMweVpUazNOU0lzSW5CMVlteHBZMHRsZVVwM2F5STZleUpqY25ZaU9pSnpaV053TWpVMmF6RWlMQ0pyZEhraU9pSkZReUlzSW5naU9pSnFOVlE0UzFGZlExOUlSR3hTYlhsRlgxcHdSamx0YkUxUlozQjROMTlmTUZKUVJIaFBWbU00ZFd0M0lpd2llU0k2SW5weWJEQldTbGxIV25oVkxYRmpaV3QyU2xZNE5HczVVMngyU1RReGFtNTNORzR5VFMxV01uQjRNR01pZlN3aWNIVnljRzl6WlhNaU9sc2lZWFYwYUdWdWRHbGpZWFJwYjI0aUxDSmhjM05sY25ScGIyNU5aWFJvYjJRaVhTd2lkSGx3WlNJNklrVmpaSE5oVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T1NKOVhTd2ljMlZ5ZG1salpYTWlPbHQ3SW1sa0lqb2liR2x1YTJWa1pHOXRZV2x1Y3lJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnZjbWxuYVc1eklqcGJJbWgwZEhCek9pOHZaR2xrTG5KdmFHbDBaM1ZzWVhScExtTnZiUzhpWFgwc0luUjVjR1VpT2lKTWFXNXJaV1JFYjIxaGFXNXpJbjBzZXlKcFpDSTZJbWgxWWlJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnBibk4wWVc1alpYTWlPbHNpYUhSMGNITTZMeTlpWlhSaExtaDFZaTV0YzJsa1pXNTBhWFI1TG1OdmJTOTJNUzR3TDJFME9USmpabVl5TFdRM016TXROREExTnkwNU5XRTFMV0UzTVdaak16WTVOV0pqT0NKZGZTd2lkSGx3WlNJNklrbGtaVzUwYVhSNVNIVmlJbjFkZlgxZExDSjFjR1JoZEdWRGIyMXRhWFJ0Wlc1MElqb2lSV2xEY1hScFpuVXdTSGc0UlVWa2JHbHJWblpJV0dwWVp6UkxiMHBaWlVWMGNEZFplR2x2UnpWWVdtUktaeUo5TENKemRXWm1hWGhFWVhSaElqcDdJbVJsYkhSaFNHRnphQ0k2SWtWcFExTlZRa2xtWVRCWFpIQlhObTVvVlRkTmFIbFNjelJ1Y1RGRGVFZzFWMVp5VWpWa1VGWllWMDlNWW1jaUxDSnlaV052ZG1WeWVVTnZiVzFwZEcxbGJuUWlPaUpGYVVGMWNHb3hSV1pzT0hkaldsUlFaVEkzWDBsR1dFSjNNamx6T0VONVNYQlJYM1V6VmtSd1Vtc3dka05SSW4xOSIsImlzcyI6ImRpZDppb246RWlDTWRWTHR6cXFXNW42elVDM19zclp4V1BDc2VWeEtYdTlGcVE4THlTMW1UQTpleUprWld4MFlTSTZleUp3WVhSamFHVnpJanBiZXlKaFkzUnBiMjRpT2lKeVpYQnNZV05sSWl3aVpHOWpkVzFsYm5RaU9uc2ljSFZpYkdsalMyVjVjeUk2VzNzaWFXUWlPaUkyTm1Sa05URm1aVEJqWVdNMFpqRmhZV1U0TVRKa01HRmhNVEE1WW1NeVlYWmpVMmxuYm1sdVowdGxlUzB5WlRrM05TSXNJbkIxWW14cFkwdGxlVXAzYXlJNmV5SmpjbllpT2lKelpXTndNalUyYXpFaUxDSnJkSGtpT2lKRlF5SXNJbmdpT2lKcU5WUTRTMUZmUTE5SVJHeFNiWGxGWDFwd1JqbHRiRTFSWjNCNE4xOWZNRkpRUkhoUFZtTTRkV3QzSWl3aWVTSTZJbnB5YkRCV1NsbEhXbmhWTFhGalpXdDJTbFk0TkdzNVUyeDJTVFF4YW01M05HNHlUUzFXTW5CNE1HTWlmU3dpY0hWeWNHOXpaWE1pT2xzaVlYVjBhR1Z1ZEdsallYUnBiMjRpTENKaGMzTmxjblJwYjI1TlpYUm9iMlFpWFN3aWRIbHdaU0k2SWtWalpITmhVMlZqY0RJMU5tc3hWbVZ5YVdacFkyRjBhVzl1UzJWNU1qQXhPU0o5WFN3aWMyVnlkbWxqWlhNaU9sdDdJbWxrSWpvaWJHbHVhMlZrWkc5dFlXbHVjeUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKdmNtbG5hVzV6SWpwYkltaDBkSEJ6T2k4dlpHbGtMbkp2YUdsMFozVnNZWFJwTG1OdmJTOGlYWDBzSW5SNWNHVWlPaUpNYVc1clpXUkViMjFoYVc1ekluMHNleUpwWkNJNkltaDFZaUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKcGJuTjBZVzVqWlhNaU9sc2lhSFIwY0hNNkx5OWlaWFJoTG1oMVlpNXRjMmxrWlc1MGFYUjVMbU52YlM5Mk1TNHdMMkUwT1RKalptWXlMV1EzTXpNdE5EQTFOeTA1TldFMUxXRTNNV1pqTXpZNU5XSmpPQ0pkZlN3aWRIbHdaU0k2SWtsa1pXNTBhWFI1U0hWaUluMWRmWDFkTENKMWNHUmhkR1ZEYjIxdGFYUnRaVzUwSWpvaVJXbERjWFJwWm5Vd1NIZzRSVVZrYkdsclZuWklXR3BZWnpSTGIwcFpaVVYwY0RkWmVHbHZSelZZV21SS1p5SjlMQ0p6ZFdabWFYaEVZWFJoSWpwN0ltUmxiSFJoU0dGemFDSTZJa1ZwUTFOVlFrbG1ZVEJYWkhCWE5tNW9WVGROYUhsU2N6UnVjVEZEZUVnMVYxWnlValZrVUZaWVYwOU1ZbWNpTENKeVpXTnZkbVZ5ZVVOdmJXMXBkRzFsYm5RaU9pSkZhVUYxY0dveFJXWnNPSGRqV2xSUVpUSTNYMGxHV0VKM01qbHpPRU41U1hCUlgzVXpWa1J3VW1zd2RrTlJJbjE5IiwibmJmIjoxNjU0NzUxMjc3LCJleHAiOjI0NDM2Njk2NzcsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9pZGVudGl0eS5mb3VuZGF0aW9uLy53ZWxsLWtub3duL2NvbnRleHRzL2RpZC1jb25maWd1cmF0aW9uLXYwLjAuanNvbmxkIl0sImlzc3VlciI6ImRpZDppb246RWlDTWRWTHR6cXFXNW42elVDM19zclp4V1BDc2VWeEtYdTlGcVE4THlTMW1UQTpleUprWld4MFlTSTZleUp3WVhSamFHVnpJanBiZXlKaFkzUnBiMjRpT2lKeVpYQnNZV05sSWl3aVpHOWpkVzFsYm5RaU9uc2ljSFZpYkdsalMyVjVjeUk2VzNzaWFXUWlPaUkyTm1Sa05URm1aVEJqWVdNMFpqRmhZV1U0TVRKa01HRmhNVEE1WW1NeVlYWmpVMmxuYm1sdVowdGxlUzB5WlRrM05TSXNJbkIxWW14cFkwdGxlVXAzYXlJNmV5SmpjbllpT2lKelpXTndNalUyYXpFaUxDSnJkSGtpT2lKRlF5SXNJbmdpT2lKcU5WUTRTMUZmUTE5SVJHeFNiWGxGWDFwd1JqbHRiRTFSWjNCNE4xOWZNRkpRUkhoUFZtTTRkV3QzSWl3aWVTSTZJbnB5YkRCV1NsbEhXbmhWTFhGalpXdDJTbFk0TkdzNVUyeDJTVFF4YW01M05HNHlUUzFXTW5CNE1HTWlmU3dpY0hWeWNHOXpaWE1pT2xzaVlYVjBhR1Z1ZEdsallYUnBiMjRpTENKaGMzTmxjblJwYjI1TlpYUm9iMlFpWFN3aWRIbHdaU0k2SWtWalpITmhVMlZqY0RJMU5tc3hWbVZ5YVdacFkyRjBhVzl1UzJWNU1qQXhPU0o5WFN3aWMyVnlkbWxqWlhNaU9sdDdJbWxrSWpvaWJHbHVhMlZrWkc5dFlXbHVjeUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKdmNtbG5hVzV6SWpwYkltaDBkSEJ6T2k4dlpHbGtMbkp2YUdsMFozVnNZWFJwTG1OdmJTOGlYWDBzSW5SNWNHVWlPaUpNYVc1clpXUkViMjFoYVc1ekluMHNleUpwWkNJNkltaDFZaUlzSW5ObGNuWnBZMlZGYm1Sd2IybHVkQ0k2ZXlKcGJuTjBZVzVqWlhNaU9sc2lhSFIwY0hNNkx5OWlaWFJoTG1oMVlpNXRjMmxrWlc1MGFYUjVMbU52YlM5Mk1TNHdMMkUwT1RKalptWXlMV1EzTXpNdE5EQTFOeTA1TldFMUxXRTNNV1pqTXpZNU5XSmpPQ0pkZlN3aWRIbHdaU0k2SWtsa1pXNTBhWFI1U0hWaUluMWRmWDFkTENKMWNHUmhkR1ZEYjIxdGFYUnRaVzUwSWpvaVJXbERjWFJwWm5Vd1NIZzRSVVZrYkdsclZuWklXR3BZWnpSTGIwcFpaVVYwY0RkWmVHbHZSelZZV21SS1p5SjlMQ0p6ZFdabWFYaEVZWFJoSWpwN0ltUmxiSFJoU0dGemFDSTZJa1ZwUTFOVlFrbG1ZVEJYWkhCWE5tNW9WVGROYUhsU2N6UnVjVEZEZUVnMVYxWnlValZrVUZaWVYwOU1ZbWNpTENKeVpXTnZkbVZ5ZVVOdmJXMXBkRzFsYm5RaU9pSkZhVUYxY0dveFJXWnNPSGRqV2xSUVpUSTNYMGxHV0VKM01qbHpPRU41U1hCUlgzVXpWa1J3VW1zd2RrTlJJbjE5IiwiaXNzdWFuY2VEYXRlIjoiMjAyMi0wNi0wOVQwNTowNzo1Ny42NjRaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDQ3LTA2LTA5VDA1OjA3OjU3LjY2NFoiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRG9tYWluTGlua2FnZUNyZWRlbnRpYWwiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6aW9uOkVpQ01kVkx0enFxVzVuNnpVQzNfc3JaeFdQQ3NlVnhLWHU5RnFROEx5UzFtVEE6ZXlKa1pXeDBZU0k2ZXlKd1lYUmphR1Z6SWpwYmV5SmhZM1JwYjI0aU9pSnlaWEJzWVdObElpd2laRzlqZFcxbGJuUWlPbnNpY0hWaWJHbGpTMlY1Y3lJNlczc2lhV1FpT2lJMk5tUmtOVEZtWlRCallXTTBaakZoWVdVNE1USmtNR0ZoTVRBNVltTXlZWFpqVTJsbmJtbHVaMHRsZVMweVpUazNOU0lzSW5CMVlteHBZMHRsZVVwM2F5STZleUpqY25ZaU9pSnpaV053TWpVMmF6RWlMQ0pyZEhraU9pSkZReUlzSW5naU9pSnFOVlE0UzFGZlExOUlSR3hTYlhsRlgxcHdSamx0YkUxUlozQjROMTlmTUZKUVJIaFBWbU00ZFd0M0lpd2llU0k2SW5weWJEQldTbGxIV25oVkxYRmpaV3QyU2xZNE5HczVVMngyU1RReGFtNTNORzR5VFMxV01uQjRNR01pZlN3aWNIVnljRzl6WlhNaU9sc2lZWFYwYUdWdWRHbGpZWFJwYjI0aUxDSmhjM05sY25ScGIyNU5aWFJvYjJRaVhTd2lkSGx3WlNJNklrVmpaSE5oVTJWamNESTFObXN4Vm1WeWFXWnBZMkYwYVc5dVMyVjVNakF4T1NKOVhTd2ljMlZ5ZG1salpYTWlPbHQ3SW1sa0lqb2liR2x1YTJWa1pHOXRZV2x1Y3lJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnZjbWxuYVc1eklqcGJJbWgwZEhCek9pOHZaR2xrTG5KdmFHbDBaM1ZzWVhScExtTnZiUzhpWFgwc0luUjVjR1VpT2lKTWFXNXJaV1JFYjIxaGFXNXpJbjBzZXlKcFpDSTZJbWgxWWlJc0luTmxjblpwWTJWRmJtUndiMmx1ZENJNmV5SnBibk4wWVc1alpYTWlPbHNpYUhSMGNITTZMeTlpWlhSaExtaDFZaTV0YzJsa1pXNTBhWFI1TG1OdmJTOTJNUzR3TDJFME9USmpabVl5TFdRM016TXROREExTnkwNU5XRTFMV0UzTVdaak16WTVOV0pqT0NKZGZTd2lkSGx3WlNJNklrbGtaVzUwYVhSNVNIVmlJbjFkZlgxZExDSjFjR1JoZEdWRGIyMXRhWFJ0Wlc1MElqb2lSV2xEY1hScFpuVXdTSGc0UlVWa2JHbHJWblpJV0dwWVp6UkxiMHBaWlVWMGNEZFplR2x2UnpWWVdtUktaeUo5TENKemRXWm1hWGhFWVhSaElqcDdJbVJsYkhSaFNHRnphQ0k2SWtWcFExTlZRa2xtWVRCWFpIQlhObTVvVlRkTmFIbFNjelJ1Y1RGRGVFZzFWMVp5VWpWa1VGWllWMDlNWW1jaUxDSnlaV052ZG1WeWVVTnZiVzFwZEcxbGJuUWlPaUpGYVVGMWNHb3hSV1pzT0hkaldsUlFaVEkzWDBsR1dFSjNNamx6T0VONVNYQlJYM1V6VmtSd1Vtc3dka05SSW4xOSIsIm9yaWdpbiI6Imh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8ifX19.Ek8mz8O9yw3ZT8ds3sfy0ELqhUJdgJM-DUpgQawubNyI2wfxM8nLeON_zzxBp1uafdsJujCb4KkFg-SKsRoD3A"
   307    ]
   308  }`
   309  
   310  	// nolint:lll
   311  	msDoc = `
   312  {
   313    "id": "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiI2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJqNVQ4S1FfQ19IRGxSbXlFX1pwRjltbE1RZ3B4N19fMFJQRHhPVmM4dWt3IiwieSI6InpybDBWSllHWnhVLXFjZWt2SlY4NGs5U2x2STQxam53NG4yTS1WMnB4MGMifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJhc3NlcnRpb25NZXRob2QiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoibGlua2VkZG9tYWlucyIsInNlcnZpY2VFbmRwb2ludCI6eyJvcmlnaW5zIjpbImh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8iXX0sInR5cGUiOiJMaW5rZWREb21haW5zIn0seyJpZCI6Imh1YiIsInNlcnZpY2VFbmRwb2ludCI6eyJpbnN0YW5jZXMiOlsiaHR0cHM6Ly9iZXRhLmh1Yi5tc2lkZW50aXR5LmNvbS92MS4wL2E0OTJjZmYyLWQ3MzMtNDA1Ny05NWE1LWE3MWZjMzY5NWJjOCJdfSwidHlwZSI6IklkZW50aXR5SHViIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlDcXRpZnUwSHg4RUVkbGlrVnZIWGpYZzRLb0pZZUV0cDdZeGlvRzVYWmRKZyJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpQ1NVQklmYTBXZHBXNm5oVTdNaHlSczRucTFDeEg1V1ZyUjVkUFZYV09MYmciLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUF1cGoxRWZsOHdjWlRQZTI3X0lGWEJ3MjlzOEN5SXBRX3UzVkRwUmswdkNRIn19",
   314    "@context": [
   315      "https://www.w3.org/ns/did/v1",
   316      {
   317        "@base": "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiI2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJqNVQ4S1FfQ19IRGxSbXlFX1pwRjltbE1RZ3B4N19fMFJQRHhPVmM4dWt3IiwieSI6InpybDBWSllHWnhVLXFjZWt2SlY4NGs5U2x2STQxam53NG4yTS1WMnB4MGMifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJhc3NlcnRpb25NZXRob2QiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoibGlua2VkZG9tYWlucyIsInNlcnZpY2VFbmRwb2ludCI6eyJvcmlnaW5zIjpbImh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8iXX0sInR5cGUiOiJMaW5rZWREb21haW5zIn0seyJpZCI6Imh1YiIsInNlcnZpY2VFbmRwb2ludCI6eyJpbnN0YW5jZXMiOlsiaHR0cHM6Ly9iZXRhLmh1Yi5tc2lkZW50aXR5LmNvbS92MS4wL2E0OTJjZmYyLWQ3MzMtNDA1Ny05NWE1LWE3MWZjMzY5NWJjOCJdfSwidHlwZSI6IklkZW50aXR5SHViIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlDcXRpZnUwSHg4RUVkbGlrVnZIWGpYZzRLb0pZZUV0cDdZeGlvRzVYWmRKZyJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpQ1NVQklmYTBXZHBXNm5oVTdNaHlSczRucTFDeEg1V1ZyUjVkUFZYV09MYmciLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUF1cGoxRWZsOHdjWlRQZTI3X0lGWEJ3MjlzOEN5SXBRX3UzVkRwUmswdkNRIn19"
   318      }
   319    ],
   320    "service": [
   321      {
   322        "id": "#linkeddomains",
   323        "type": "LinkedDomains",
   324        "serviceEndpoint": {
   325          "origins": [
   326            "https://did.rohitgulati.com/"
   327          ]
   328        }
   329      },
   330      {
   331        "id": "#hub",
   332        "type": "IdentityHub",
   333        "serviceEndpoint": {
   334          "instances": [
   335            "https://beta.hub.msidentity.com/v1.0/a492cff2-d733-4057-95a5-a71fc3695bc8"
   336          ],
   337          "origins": []
   338        }
   339      }
   340    ],
   341    "verificationMethod": [
   342      {
   343        "id": "#66dd51fe0cac4f1aae812d0aa109bc2avcSigningKey-2e975",
   344        "controller": "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiI2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJqNVQ4S1FfQ19IRGxSbXlFX1pwRjltbE1RZ3B4N19fMFJQRHhPVmM4dWt3IiwieSI6InpybDBWSllHWnhVLXFjZWt2SlY4NGs5U2x2STQxam53NG4yTS1WMnB4MGMifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJhc3NlcnRpb25NZXRob2QiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoibGlua2VkZG9tYWlucyIsInNlcnZpY2VFbmRwb2ludCI6eyJvcmlnaW5zIjpbImh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8iXX0sInR5cGUiOiJMaW5rZWREb21haW5zIn0seyJpZCI6Imh1YiIsInNlcnZpY2VFbmRwb2ludCI6eyJpbnN0YW5jZXMiOlsiaHR0cHM6Ly9iZXRhLmh1Yi5tc2lkZW50aXR5LmNvbS92MS4wL2E0OTJjZmYyLWQ3MzMtNDA1Ny05NWE1LWE3MWZjMzY5NWJjOCJdfSwidHlwZSI6IklkZW50aXR5SHViIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlDcXRpZnUwSHg4RUVkbGlrVnZIWGpYZzRLb0pZZUV0cDdZeGlvRzVYWmRKZyJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpQ1NVQklmYTBXZHBXNm5oVTdNaHlSczRucTFDeEg1V1ZyUjVkUFZYV09MYmciLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUF1cGoxRWZsOHdjWlRQZTI3X0lGWEJ3MjlzOEN5SXBRX3UzVkRwUmswdkNRIn19",
   345        "type": "EcdsaSecp256k1VerificationKey2019",
   346        "publicKeyJwk": {
   347          "kty": "EC",
   348          "crv": "secp256k1",
   349          "x": "j5T8KQ_C_HDlRmyE_ZpF9mlMQgpx7__0RPDxOVc8ukw",
   350          "y": "zrl0VJYGZxU-qcekvJV84k9SlvI41jnw4n2M-V2px0c"
   351        }
   352      }
   353    ],
   354    "authentication": [
   355      "#66dd51fe0cac4f1aae812d0aa109bc2avcSigningKey-2e975"
   356    ],
   357    "assertionMethod": [
   358      "#66dd51fe0cac4f1aae812d0aa109bc2avcSigningKey-2e975"
   359    ]
   360  }`
   361  
   362  	msDocMetadata = `
   363  {
   364    "method": {
   365      "published": true,
   366      "recoveryCommitment": "EiAupj1Efl8wcZTPe27_IFXBw29s8CyIpQ_u3VDpRk0vCQ",
   367      "updateCommitment": "EiCqtifu0Hx8EEdlikVvHXjXg4KoJYeEtp7YxioG5XZdJg"
   368    },
   369    "equivalentId": [
   370      "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA"
   371    ],
   372    "canonicalId": "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA"
   373  }`
   374  
   375  	// nolint:lll
   376  	msResolutionMetadata = `
   377  {
   378    "contentType": "application/did+ld+json",
   379    "pattern": "^(did:ion:(?!test).+)$",
   380    "driverUrl": "http://driver-did-ion:8080/1.0/identifiers/",
   381    "duration": 403,
   382    "did": {
   383      "didString": "did:ion:EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiI2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJqNVQ4S1FfQ19IRGxSbXlFX1pwRjltbE1RZ3B4N19fMFJQRHhPVmM4dWt3IiwieSI6InpybDBWSllHWnhVLXFjZWt2SlY4NGs5U2x2STQxam53NG4yTS1WMnB4MGMifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJhc3NlcnRpb25NZXRob2QiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoibGlua2VkZG9tYWlucyIsInNlcnZpY2VFbmRwb2ludCI6eyJvcmlnaW5zIjpbImh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8iXX0sInR5cGUiOiJMaW5rZWREb21haW5zIn0seyJpZCI6Imh1YiIsInNlcnZpY2VFbmRwb2ludCI6eyJpbnN0YW5jZXMiOlsiaHR0cHM6Ly9iZXRhLmh1Yi5tc2lkZW50aXR5LmNvbS92MS4wL2E0OTJjZmYyLWQ3MzMtNDA1Ny05NWE1LWE3MWZjMzY5NWJjOCJdfSwidHlwZSI6IklkZW50aXR5SHViIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlDcXRpZnUwSHg4RUVkbGlrVnZIWGpYZzRLb0pZZUV0cDdZeGlvRzVYWmRKZyJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpQ1NVQklmYTBXZHBXNm5oVTdNaHlSczRucTFDeEg1V1ZyUjVkUFZYV09MYmciLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUF1cGoxRWZsOHdjWlRQZTI3X0lGWEJ3MjlzOEN5SXBRX3UzVkRwUmswdkNRIn19",
   384      "methodSpecificId": "EiCMdVLtzqqW5n6zUC3_srZxWPCseVxKXu9FqQ8LyS1mTA:eyJkZWx0YSI6eyJwYXRjaGVzIjpbeyJhY3Rpb24iOiJyZXBsYWNlIiwiZG9jdW1lbnQiOnsicHVibGljS2V5cyI6W3siaWQiOiI2NmRkNTFmZTBjYWM0ZjFhYWU4MTJkMGFhMTA5YmMyYXZjU2lnbmluZ0tleS0yZTk3NSIsInB1YmxpY0tleUp3ayI6eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJqNVQ4S1FfQ19IRGxSbXlFX1pwRjltbE1RZ3B4N19fMFJQRHhPVmM4dWt3IiwieSI6InpybDBWSllHWnhVLXFjZWt2SlY4NGs5U2x2STQxam53NG4yTS1WMnB4MGMifSwicHVycG9zZXMiOlsiYXV0aGVudGljYXRpb24iLCJhc3NlcnRpb25NZXRob2QiXSwidHlwZSI6IkVjZHNhU2VjcDI1NmsxVmVyaWZpY2F0aW9uS2V5MjAxOSJ9XSwic2VydmljZXMiOlt7ImlkIjoibGlua2VkZG9tYWlucyIsInNlcnZpY2VFbmRwb2ludCI6eyJvcmlnaW5zIjpbImh0dHBzOi8vZGlkLnJvaGl0Z3VsYXRpLmNvbS8iXX0sInR5cGUiOiJMaW5rZWREb21haW5zIn0seyJpZCI6Imh1YiIsInNlcnZpY2VFbmRwb2ludCI6eyJpbnN0YW5jZXMiOlsiaHR0cHM6Ly9iZXRhLmh1Yi5tc2lkZW50aXR5LmNvbS92MS4wL2E0OTJjZmYyLWQ3MzMtNDA1Ny05NWE1LWE3MWZjMzY5NWJjOCJdfSwidHlwZSI6IklkZW50aXR5SHViIn1dfX1dLCJ1cGRhdGVDb21taXRtZW50IjoiRWlDcXRpZnUwSHg4RUVkbGlrVnZIWGpYZzRLb0pZZUV0cDdZeGlvRzVYWmRKZyJ9LCJzdWZmaXhEYXRhIjp7ImRlbHRhSGFzaCI6IkVpQ1NVQklmYTBXZHBXNm5oVTdNaHlSczRucTFDeEg1V1ZyUjVkUFZYV09MYmciLCJyZWNvdmVyeUNvbW1pdG1lbnQiOiJFaUF1cGoxRWZsOHdjWlRQZTI3X0lGWEJ3MjlzOEN5SXBRX3UzVkRwUmswdkNRIn19",
   385      "method": "ion"
   386    }
   387  }`
   388  
   389  	msResolutionResponse = `{
   390    "@context": "https://w3id.org/did-resolution/v1",
   391    "didDocument": ` + msDoc + `,
   392    "didDocumentMetadata": ` + msDocMetadata + `,
   393    "didResolutionMetadata": ` + msResolutionMetadata + `
   394  }`
   395  )