func CreateCustomPresentation(vcBytes []byte, vdr vdrapi.Registry,
	ldpContext *verifiable.LinkedDataProofContext) ([]byte, error) {
	loader, err := DocumentLoader()
	if err != nil {
		return nil, fmt.Errorf("create document loader: %w", err)
	}
	vc, err := verifiable.ParseCredential(vcBytes,
		verifiable.WithPublicKeyFetcher(verifiable.NewVDRKeyResolver(vdr).PublicKeyFetcher()),
		verifiable.WithJSONLDDocumentLoader(loader))
	if err != nil {
		return nil, err
	}
	vp, err := verifiable.NewPresentation(verifiable.WithCredentials(vc))
	if err != nil {
		return nil, err
	}
	err = vp.AddLinkedDataProof(ldpContext, jsonld.WithDocumentLoader(loader))
	if err != nil {
		return nil, err
	}
	return json.Marshal(vp)
}
CreateCustomPresentation creates verifiable presentation from custom linked data proof context
package bddutil
import (
	"crypto/ed25519"
	"crypto/tls"
	_ "embed"  
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"reflect"
	"strings"
	"time"
	"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
	docdid "github.com/hyperledger/aries-framework-go/pkg/doc/did"
	"github.com/hyperledger/aries-framework-go/pkg/doc/ld"
	"github.com/hyperledger/aries-framework-go/pkg/doc/ldcontext"
	"github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
	"github.com/hyperledger/aries-framework-go/pkg/doc/verifiable"
	vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
	ldstore "github.com/hyperledger/aries-framework-go/pkg/store/ld"
	"github.com/trustbloc/edge-core/pkg/log"
)
var logger = log.New("bddutil")
type ProofDataOpts struct {
	Challenge string
	Domain    string
}
func ResolveDID(vdrRegistry vdrapi.Registry, did string, maxRetry int) (*docdid.Doc, error) {
	var docResolution *docdid.DocResolution
	for i := 1; i <= maxRetry; i++ {
		var err error
		docResolution, err = vdrRegistry.Resolve(did)
		if err != nil {
			if !strings.Contains(err.Error(), "DID does not exist") {
				return nil, err
			}
			fmt.Printf("did %s not found will retry %d of %d\n", did, i, maxRetry)
			time.Sleep(3 * time.Second)  
			continue
		}
		if strings.Contains(docResolution.DIDDocument.ID, "did:v1") {
			split := strings.Split(docResolution.DIDDocument.AssertionMethod[0].VerificationMethod.ID, "#")
			if strings.Contains(docResolution.DIDDocument.ID, split[1]) {
				fmt.Printf("v1 did %s not register yet will retry %d of %d\n", did, i, maxRetry)
				time.Sleep(3 * time.Second)  
				continue
			}
		}
	}
	return docResolution.DIDDocument, nil
}
func HTTPDo(method, url, contentType, token string, body io.Reader) (*http.Response, error) {
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}
	if contentType != "" {
		req.Header.Add("Content-Type", contentType)
	}
	if token != "" {
		req.Header.Add("Authorization", "Bearer "+token)
	}
	return http.DefaultClient.Do(req)
}
func HTTPSDo(method, url, contentType, token string, body io.Reader, tlsConfig *tls.Config) (*http.Response, error) {
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}
	if contentType != "" {
		req.Header.Add("Content-Type", contentType)
	}
	if token != "" {
		req.Header.Add("Authorization", "Bearer "+token)
	}
	c := &http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}
	return c.Do(req)
}
func GetSigner(privKey []byte) verifiable.Signer {
	return &signer{privateKey: privKey}
}
type signer struct {
	privateKey []byte
}
func (s *signer) Sign(doc []byte) ([]byte, error) {
	if l := len(s.privateKey); l != ed25519.PrivateKeySize {
		return nil, errors.New("ed25519: bad private key length")
	}
	return ed25519.Sign(s.privateKey, doc), nil
}
func ExpectedStringError(expected, actual string) error {
	return fmt.Errorf("expected %s but got %s instead", expected, actual)
}
func ExpectedStatusCodeError(expected, actual int, respBytes []byte) error {
	return fmt.Errorf("expected status code %d but got status code %d with response body %s instead",
		expected, actual, respBytes)
}
func AreEqualJSON(b1, b2 []byte) (bool, error) {
	var o1, o2 interface{}
	err := json.Unmarshal(b1, &o1)
	if err != nil {
		return false, fmt.Errorf("error mashalling bytes 1 : %w", err)
	}
	err = json.Unmarshal(b2, &o2)
	if err != nil {
		return false, fmt.Errorf("error mashalling bytes 2 : %w", err)
	}
	return reflect.DeepEqual(o1, o2), nil
}
func CloseResponseBody(respBody io.Closer) {
	err := respBody.Close()
	if err != nil {
		logger.Errorf("Failed to close response body: %s", err.Error())
	}
}
func GetProfileNameKey(user string) string {
	return user + "-profileName"
}
func GetCredentialKey(user string) string {
	return user + "-vc"
}
func GetPresentationKey(user string) string {
	return user + "-vp"
}
func GetOptionsKey(user string) string {
	return user + "-opts"
}
func GetProofChallengeKey(user string) string {
	return user + "-challenge"
}
func GetProofDomainKey(user string) string {
	return user + "-domain"
}
func GetIssuerHolderCommKey(issuer, holder string) string {
	return issuer + holder + "-data"
}
func GetDIDDocKey(user string) string {
	return user + "-did-doc"
}