diff --git a/pkg/doc/sdjwt/example_test.go b/pkg/doc/sdjwt/example_test.go
new file mode 100644
index 000000000..47e33dd98
--- /dev/null
+++ b/pkg/doc/sdjwt/example_test.go
@@ -0,0 +1,284 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package sdjwt
+
+import (
+	"crypto/ed25519"
+	"crypto/rand"
+	"encoding/json"
+	"fmt"
+	"time"
+
+	"github.com/go-jose/go-jose/v3/jwt"
+
+	"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport"
+	afjwt "github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/holder"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/issuer"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/verifier"
+)
+
+func ExampleSimpleClaims() { //nolint:govet
+	signer, signatureVerifier, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"given_name": "Albert",
+		"last_name":  "Smith",
+	}
+
+	// Issuer will issue SD-JWT for specified claims.
+	token, err := issuer.New(testIssuer, claims, nil, signer)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	combinedFormatForIssuance, err := token.Serialize(false)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	// Holder will parse combined format for issuance and hold on to that
+	// combined format for issuance and the claims that can be selected.
+	holderClaims, err := holder.Parse(combinedFormatForIssuance, holder.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("holder failed to parse SD-JWT: %w", err.Error())
+	}
+
+	// The Holder will only select given_name
+	selectedDisclosures := getDisclosuresFromClaimNames([]string{"given_name"}, holderClaims)
+
+	// Holder will disclose only sub-set of claims to verifier.
+	combinedFormatForPresentation, err := holder.CreatePresentation(combinedFormatForIssuance, selectedDisclosures)
+	if err != nil {
+		fmt.Println("holder failed to create presentation: %w", err.Error())
+	}
+
+	// Verifier will validate combined format for presentation and create verified claims.
+	verifiedClaims, err := verifier.Parse(combinedFormatForPresentation,
+		verifier.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("verifier failed to parse holder presentation: %w", err.Error())
+	}
+
+	verifiedClaimsJSON, err := marshalObj(verifiedClaims)
+	if err != nil {
+		fmt.Println("verifier failed to marshal verified claims: %w", err.Error())
+	}
+
+	fmt.Println(verifiedClaimsJSON)
+
+	// Output: {
+	//	"given_name": "Albert",
+	//	"iss": "https://example.com/issuer"
+	//}
+}
+
+func ExampleComplexClaimsWithHolderBinding() { //nolint:govet
+	signer, signatureVerifier, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	holderSigner, holderJWK, err := setUpHolderBinding()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"sub":          "john_doe_42",
+		"given_name":   "John",
+		"family_name":  "Doe",
+		"email":        "johndoe@example.com",
+		"phone_number": "+1-202-555-0101",
+		"birthdate":    "1940-01-01",
+		"address": map[string]interface{}{
+			"street_address": "123 Main St",
+			"locality":       "Anytown",
+			"region":         "Anystate",
+			"country":        "US",
+		},
+	}
+
+	// Issuer will issue SD-JWT for specified claims. Structured claims not selected as an option hence complex object
+	// address will be treated as an object not as a set of properties. Holder public key is provided therefore it will
+	// be added as "cnf" claim.
+	token, err := issuer.New(testIssuer, claims, nil, signer,
+		issuer.WithHolderPublicKey(holderJWK),
+	)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	combinedFormatForIssuance, err := token.Serialize(false)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	// Holder will parse combined format for issuance and hold on to that
+	// combined format for issuance and the claims that can be selected.
+	holderClaims, err := holder.Parse(combinedFormatForIssuance, holder.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("holder failed to parse SD-JWT: %w", err.Error())
+	}
+
+	// The Holder will only select given_name, address
+	selectedDisclosures := getDisclosuresFromClaimNames([]string{"given_name", "address"}, holderClaims)
+
+	// Holder will disclose only sub-set of claims to verifier.
+	combinedFormatForPresentation, err := holder.CreatePresentation(combinedFormatForIssuance, selectedDisclosures,
+		holder.WithHolderBinding(&holder.BindingInfo{
+			Payload: holder.BindingPayload{
+				Nonce:    "nonce",
+				Audience: "https://test.com/verifier",
+				IssuedAt: jwt.NewNumericDate(time.Now()),
+			},
+			Signer: holderSigner,
+		}))
+	if err != nil {
+		fmt.Println("holder failed to create presentation: %w", err.Error())
+	}
+
+	// Verifier will validate combined format for presentation and create verified claims.
+	verifiedClaims, err := verifier.Parse(combinedFormatForPresentation,
+		verifier.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("verifier failed to parse holder presentation: %w", err.Error())
+	}
+
+	addressClaimsJSON, err := marshalObj(verifiedClaims["address"])
+	if err != nil {
+		fmt.Println("verifier failed to marshal verified claims: %w", err.Error())
+	}
+
+	fmt.Println(addressClaimsJSON)
+
+	// Output: {
+	//	"country": "US",
+	//	"locality": "Anytown",
+	//	"region": "Anystate",
+	//	"street_address": "123 Main St"
+	//}
+}
+
+func ExampleComplexObjectWithStructuredClaims() { //nolint:govet
+	signer, signatureVerifier, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"sub":          "john_doe_42",
+		"given_name":   "John",
+		"family_name":  "Doe",
+		"email":        "johndoe@example.com",
+		"phone_number": "+1-202-555-0101",
+		"birthdate":    "1940-01-01",
+		"address": map[string]interface{}{
+			"street_address": "123 Main St",
+			"locality":       "Anytown",
+			"region":         "Anystate",
+			"country":        "US",
+		},
+	}
+
+	// Issuer will issue SD-JWT for specified claims.
+	token, err := issuer.New(testIssuer, claims, nil, signer,
+		issuer.WithStructuredClaims(true),
+		issuer.WithNonSelectivelyDisclosableClaims([]string{"address.country"}),
+	)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	combinedFormatForIssuance, err := token.Serialize(false)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	// Holder will parse combined format for issuance and hold on to that
+	// combined format for issuance and the claims that can be selected.
+	holderClaims, err := holder.Parse(combinedFormatForIssuance, holder.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("holder failed to parse SD-JWT: %w", err.Error())
+	}
+
+	// The Holder will only select given_name, street_address
+	selectedDisclosures := getDisclosuresFromClaimNames([]string{"given_name", "street_address"}, holderClaims)
+
+	// Holder will disclose only sub-set of claims to verifier.
+	combinedFormatForPresentation, err := holder.CreatePresentation(combinedFormatForIssuance, selectedDisclosures)
+	if err != nil {
+		fmt.Println("holder failed to create presentation: %w", err.Error())
+	}
+
+	// Verifier will validate combined format for presentation and create verified claims.
+	verifiedClaims, err := verifier.Parse(combinedFormatForPresentation,
+		verifier.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("verifier failed to parse holder presentation: %w", err.Error())
+	}
+
+	verifiedClaimsJSON, err := marshalObj(verifiedClaims)
+	if err != nil {
+		fmt.Println("verifier failed to marshal verified claims: %w", err.Error())
+	}
+
+	fmt.Println(verifiedClaimsJSON)
+
+	// Output: {
+	//	"address": {
+	//		"country": "US",
+	//		"street_address": "123 Main St"
+	//	},
+	//	"given_name": "John",
+	//	"iss": "https://example.com/issuer"
+	//}
+}
+func setUp() (*afjwt.JoseED25519Signer, *afjwt.JoseEd25519Verifier, error) {
+	issuerPublicKey, issuerPrivateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	signer := afjwt.NewEd25519Signer(issuerPrivateKey)
+
+	signatureVerifier, err := afjwt.NewEd25519Verifier(issuerPublicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return signer, signatureVerifier, nil
+}
+
+func setUpHolderBinding() (*afjwt.JoseED25519Signer, *jwk.JWK, error) {
+	holderPublicKey, holderPrivateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	holderPublicJWK, err := jwksupport.JWKFromKey(holderPublicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	holderSigner := afjwt.NewEd25519Signer(holderPrivateKey)
+
+	return holderSigner, holderPublicJWK, nil
+}
+
+func marshalObj(obj interface{}) (string, error) {
+	objBytes, err := json.Marshal(obj)
+	if err != nil {
+		fmt.Println("failed to marshal object: %w", err.Error())
+	}
+
+	return prettyPrint(objBytes)
+}
diff --git a/pkg/doc/sdjwt/holder/example_test.go b/pkg/doc/sdjwt/holder/example_test.go
new file mode 100644
index 000000000..320e28899
--- /dev/null
+++ b/pkg/doc/sdjwt/holder/example_test.go
@@ -0,0 +1,216 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package holder
+
+import (
+	"bytes"
+	"crypto/ed25519"
+	"crypto/rand"
+	"encoding/json"
+	"fmt"
+	"sort"
+	"time"
+
+	"github.com/go-jose/go-jose/v3/jwt"
+
+	"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/jose/jwk/jwksupport"
+	afjwt "github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/common"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/issuer"
+)
+
+func ExampleParse() {
+	signer, signatureVerifier, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"given_name": "Albert",
+		"last_name":  "Smith",
+	}
+
+	// Issuer will issue SD-JWT for specified claims. Salt function is only provided to keep example outcome the same.
+	token, err := issuer.New(testIssuer, claims, nil, signer,
+		issuer.WithSaltFnc(func() (string, error) {
+			return "3jqcb67z9wks08zwiK7EyQ", nil
+		}))
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	combinedFormatForIssuance, err := token.Serialize(false)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	// Holder will parse combined format for issuance and hold on to that
+	// combined format for issuance and the claims that can be selected.
+	holderClaims, err := Parse(combinedFormatForIssuance, WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("holder failed to parse SD-JWT: %w", err.Error())
+	}
+
+	// Sort by claim name, keeping original order or equal elements.
+	sort.SliceStable(holderClaims, func(i, j int) bool {
+		return holderClaims[i].Name < holderClaims[j].Name
+	})
+
+	holderClaimsJSON, err := marshalObj(holderClaims)
+	if err != nil {
+		fmt.Println("verifier failed to marshal holder claims: %w", err.Error())
+	}
+
+	fmt.Println(holderClaimsJSON)
+
+	// Output: [
+	//	{
+	//		"Disclosure": "WyIzanFjYjY3ejl3a3MwOHp3aUs3RXlRIiwiZ2l2ZW5fbmFtZSIsIkFsYmVydCJd",
+	//		"Name": "given_name",
+	//		"Value": "Albert"
+	//	},
+	//	{
+	//		"Disclosure": "WyIzanFjYjY3ejl3a3MwOHp3aUs3RXlRIiwibGFzdF9uYW1lIiwiU21pdGgiXQ",
+	//		"Name": "last_name",
+	//		"Value": "Smith"
+	//	}
+	//]
+}
+
+func ExampleCreatePresentation() {
+	signer, signatureVerifier, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	holderSigner, holderJWK, err := setUpHolderBinding()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"given_name": "Albert",
+		"last_name":  "Smith",
+	}
+
+	// Issuer will issue SD-JWT for specified claims and holder public key.
+	token, err := issuer.New(testIssuer, claims, nil, signer,
+		issuer.WithHolderPublicKey(holderJWK))
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	combinedFormatForIssuance, err := token.Serialize(false)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	// Holder will parse combined format for issuance and hold on to that
+	// combined format for issuance and the claims that can be selected.
+	holderClaims, err := Parse(combinedFormatForIssuance, WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("holder failed to parse SD-JWT: %w", err.Error())
+	}
+
+	// The Holder will only select given_name
+	selectedDisclosures := getDisclosuresFromClaimNames([]string{"given_name"}, holderClaims)
+
+	// Holder will disclose only sub-set of claims to verifier and create holder binding for the verifier.
+	combinedFormatForPresentation, err := CreatePresentation(combinedFormatForIssuance, selectedDisclosures,
+		WithHolderBinding(&BindingInfo{
+			Payload: BindingPayload{
+				Nonce:    "nonce",
+				Audience: "https://test.com/verifier",
+				IssuedAt: jwt.NewNumericDate(time.Now()),
+			},
+			Signer: holderSigner,
+		}))
+	if err != nil {
+		fmt.Println("holder failed to create presentation: %w", err.Error())
+	}
+
+	cfp := common.ParseCombinedFormatForPresentation(combinedFormatForPresentation)
+
+	fmt.Println(cfp.HolderBinding != "")
+
+	// Output: true
+}
+
+func setUp() (*afjwt.JoseED25519Signer, *afjwt.JoseEd25519Verifier, error) {
+	issuerPublicKey, issuerPrivateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	signer := afjwt.NewEd25519Signer(issuerPrivateKey)
+
+	signatureVerifier, err := afjwt.NewEd25519Verifier(issuerPublicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return signer, signatureVerifier, nil
+}
+
+func setUpHolderBinding() (*afjwt.JoseED25519Signer, *jwk.JWK, error) {
+	holderPublicKey, holderPrivateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	holderPublicJWK, err := jwksupport.JWKFromKey(holderPublicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	holderSigner := afjwt.NewEd25519Signer(holderPrivateKey)
+
+	return holderSigner, holderPublicJWK, nil
+}
+
+func marshalObj(obj interface{}) (string, error) {
+	objBytes, err := json.Marshal(obj)
+	if err != nil {
+		fmt.Println("failed to marshal object: %w", err.Error())
+	}
+
+	return prettyPrint(objBytes)
+}
+
+func prettyPrint(msg []byte) (string, error) {
+	var prettyJSON bytes.Buffer
+
+	err := json.Indent(&prettyJSON, msg, "", "\t")
+	if err != nil {
+		return "", err
+	}
+
+	return prettyJSON.String(), nil
+}
+
+func getDisclosuresFromClaimNames(selectedClaimNames []string, claims []*Claim) []string {
+	var disclosures []string
+
+	for _, c := range claims {
+		if contains(selectedClaimNames, c.Name) {
+			disclosures = append(disclosures, c.Disclosure)
+		}
+	}
+
+	return disclosures
+}
+
+func contains(values []string, val string) bool {
+	for _, v := range values {
+		if v == val {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/pkg/doc/sdjwt/holder/holder.go b/pkg/doc/sdjwt/holder/holder.go
index 565871485..0d94f46c4 100644
--- a/pkg/doc/sdjwt/holder/holder.go
+++ b/pkg/doc/sdjwt/holder/holder.go
@@ -4,6 +4,7 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
 */
 
+// Package holder enables the Holder: an entity that receives SD-JWTs from the Issuer and has control over them.
 package holder
 
 import (
@@ -47,6 +48,20 @@ func WithSignatureVerifier(signatureVerifier jose.SignatureVerifier) ParseOpt {
 }
 
 // Parse parses issuer SD-JWT and returns claims that can be selected.
+// The Holder MUST perform the following (or equivalent) steps when receiving a Combined Format for Issuance:
+//
+//   - Separate the SD-JWT and the Disclosures in the Combined Format for Issuance.
+//
+//   - Hash all the Disclosures separately.
+//
+//   - Find the places in the SD-JWT where the digests of the Disclosures are included.
+//
+//   - If any of the digests cannot be found in the SD-JWT, the Holder MUST reject the SD-JWT.
+//
+//   - Decode Disclosures and obtain plaintext of the claim values.
+//
+//     It is up to the Holder how to maintain the mapping between the Disclosures and the plaintext claim values to
+//     be able to display them to the End-User when needed.
 func Parse(combinedFormatForIssuance string, opts ...ParseOpt) ([]*Claim, error) {
 	pOpts := &parseOpts{
 		sigVerifier: &NoopSignatureVerifier{},
@@ -126,6 +141,12 @@ func WithHolderBinding(info *BindingInfo) Option {
 // CreatePresentation is a convenience method to assemble combined format for presentation
 // using selected disclosures (claimsToDisclose) and optional holder binding.
 // This call assumes that combinedFormatForIssuance has already been parsed and verified using Parse() function.
+//
+// For presentation to a Verifier, the Holder MUST perform the following (or equivalent) steps:
+//   - Decide which Disclosures to release to the Verifier, obtaining proper End-User consent if necessary.
+//   - If Holder Binding is required, create a Holder Binding JWT.
+//   - Create the Combined Format for Presentation from selected Disclosures and Holder Binding JWT(if applicable).
+//   - Send the Presentation to the Verifier.
 func CreatePresentation(combinedFormatForIssuance string, claimsToDisclose []string, opts ...Option) (string, error) {
 	hOpts := &options{}
 
diff --git a/pkg/doc/sdjwt/issuer/example_test.go b/pkg/doc/sdjwt/issuer/example_test.go
new file mode 100644
index 000000000..58550a02e
--- /dev/null
+++ b/pkg/doc/sdjwt/issuer/example_test.go
@@ -0,0 +1,95 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package issuer
+
+import (
+	"crypto/ed25519"
+	"crypto/rand"
+	"encoding/json"
+	"fmt"
+
+	afjwt "github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
+)
+
+func ExampleNew() {
+	signer, _, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"last_name": "Smith",
+		"address": map[string]interface{}{
+			"street_address": "123 Main St",
+			"country":        "US",
+		},
+	}
+
+	// Issuer will issue SD-JWT for specified claims. Salt function is only provided to keep example outcome the same.
+	token, err := New("https://example.com/issuer", claims, nil, signer,
+		WithStructuredClaims(true),
+		WithNonSelectivelyDisclosableClaims([]string{"address.country"}),
+		WithSaltFnc(func() (string, error) {
+			return sampleSalt, nil
+		}))
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	var decoded map[string]interface{}
+
+	err = token.DecodeClaims(&decoded)
+	if err != nil {
+		fmt.Println("failed to decode SD-JWT claims: %w", err.Error())
+	}
+
+	issuerClaimsJSON, err := marshalObj(decoded)
+	if err != nil {
+		fmt.Println("verifier failed to marshal verified claims: %w", err.Error())
+	}
+
+	fmt.Println(issuerClaimsJSON)
+
+	// Output: {
+	//	"_sd": [
+	//		"V9-Eiizd3iJpdlxojQuwps44Zba7z6R08S7rPCDg_wU"
+	//	],
+	//	"_sd_alg": "sha-256",
+	//	"address": {
+	//		"_sd": [
+	//			"tD1XVFffEo0KTGuvHn9UlXCBgt3vot5xAanqXMdvVMg"
+	//		],
+	//		"country": "US"
+	//	},
+	//	"iss": "https://example.com/issuer"
+	//}
+}
+
+func setUp() (*afjwt.JoseED25519Signer, *afjwt.JoseEd25519Verifier, error) {
+	issuerPublicKey, issuerPrivateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	signer := afjwt.NewEd25519Signer(issuerPrivateKey)
+
+	signatureVerifier, err := afjwt.NewEd25519Verifier(issuerPublicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return signer, signatureVerifier, nil
+}
+
+func marshalObj(obj interface{}) (string, error) {
+	objBytes, err := json.Marshal(obj)
+	if err != nil {
+		fmt.Println("failed to marshal object: %w", err.Error())
+	}
+
+	return prettyPrint(objBytes)
+}
diff --git a/pkg/doc/sdjwt/issuer/issuer.go b/pkg/doc/sdjwt/issuer/issuer.go
index 01acb48df..6ae847d58 100644
--- a/pkg/doc/sdjwt/issuer/issuer.go
+++ b/pkg/doc/sdjwt/issuer/issuer.go
@@ -4,6 +4,40 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
 */
 
+/*
+Package issuer enables the Issuer: An entity that creates SD-JWTs.
+
+An SD-JWT is a digitally signed document containing digests over the claims
+(per claim: a random salt, the claim name and the claim value).
+It MAY further contain clear-text claims that are always disclosed to the Verifier.
+It MUST be digitally signed using the Issuer's private key.
+
+	SD-JWT-DOC = (METADATA, SD-CLAIMS, NON-SD-CLAIMS)
+	SD-JWT = SD-JWT-DOC | SIG(SD-JWT-DOC, ISSUER-PRIV-KEY)
+
+SD-CLAIMS is an array of digest values that ensure the integrity of
+and map to the respective Disclosures.  Digest values are calculated
+over the Disclosures, each of which contains the claim name (CLAIM-NAME),
+the claim value (CLAIM-VALUE), and a random salt (SALT).
+Digests are calculated using a hash function:
+
+SD-CLAIMS = (
+HASH(SALT, CLAIM-NAME, CLAIM-VALUE)
+)*
+
+SD-CLAIMS can also be nested deeper to capture more complex objects.
+
+The Issuer further creates a set of Disclosures for all claims in the
+SD-JWT. The Disclosures are sent to the Holder together with the SD-JWT:
+
+DISCLOSURES = (
+(SALT, CLAIM-NAME, CLAIM-VALUE)
+)*
+
+The SD-JWT and the Disclosures are sent to the Holder by the Issuer:
+
+COMBINED-ISSUANCE = SD-JWT | DISCLOSURES
+*/
 package issuer
 
 import (
@@ -76,56 +110,59 @@ func WithJSONMarshaller(jsonMarshal func(v interface{}) ([]byte, error)) NewOpt
 	}
 }
 
-// WithSaltFnc is option is for marshalling disclosure.
+// WithSaltFnc is an option for generating salt. Mostly used for testing.
+// A new salt MUST be chosen for each claim independently of other salts.
+// The RECOMMENDED minimum length of the randomly-generated portion of the salt is 128 bits.
+// It is RECOMMENDED to base64url-encode the salt value, producing a string.
 func WithSaltFnc(fnc func() (string, error)) NewOpt {
 	return func(opts *newOpts) {
 		opts.getSalt = fnc
 	}
 }
 
-// WithIssuedAt is an option for SD-JWT payload.
+// WithIssuedAt is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithIssuedAt(issuedAt *jwt.NumericDate) NewOpt {
 	return func(opts *newOpts) {
 		opts.IssuedAt = issuedAt
 	}
 }
 
-// WithAudience is an option for SD-JWT payload.
+// WithAudience is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithAudience(audience string) NewOpt {
 	return func(opts *newOpts) {
 		opts.Audience = audience
 	}
 }
 
-// WithExpiry is an option for SD-JWT payload.
+// WithExpiry is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithExpiry(expiry *jwt.NumericDate) NewOpt {
 	return func(opts *newOpts) {
 		opts.Expiry = expiry
 	}
 }
 
-// WithNotBefore is an option for SD-JWT payload.
+// WithNotBefore is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithNotBefore(notBefore *jwt.NumericDate) NewOpt {
 	return func(opts *newOpts) {
 		opts.NotBefore = notBefore
 	}
 }
 
-// WithSubject is an option for SD-JWT payload.
+// WithSubject is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithSubject(subject string) NewOpt {
 	return func(opts *newOpts) {
 		opts.Subject = subject
 	}
 }
 
-// WithJTI is an option for SD-JWT payload.
+// WithJTI is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithJTI(jti string) NewOpt {
 	return func(opts *newOpts) {
 		opts.JTI = jti
 	}
 }
 
-// WithID is an option for SD-JWT payload.
+// WithID is an option for SD-JWT payload. This is a clear-text claim that is always disclosed.
 func WithID(id string) NewOpt {
 	return func(opts *newOpts) {
 		opts.ID = id
@@ -133,6 +170,10 @@ func WithID(id string) NewOpt {
 }
 
 // WithHolderPublicKey is an option for SD-JWT payload.
+// The Holder can prove legitimate possession of an SD-JWT by proving control over the same private key during
+// the issuance and presentation. An SD-JWT with Holder Binding contains a public key or a reference to a public key
+// that matches to the private key controlled by the Holder.
+// The "cnf" claim value MUST represent only a single proof-of-possession key. This implementation is using CNF "jwk".
 func WithHolderPublicKey(jwk *jwk.JWK) NewOpt {
 	return func(opts *newOpts) {
 		opts.HolderPublicKey = jwk
@@ -181,6 +222,16 @@ func WithNonSelectivelyDisclosableClaims(nonSDClaims []string) NewOpt {
 }
 
 // New creates new signed Selective Disclosure JWT based on input claims.
+// The Issuer MUST create a Disclosure for each selectively disclosable claim as follows:
+// Create an array of three elements in this order:
+//	A salt value. Generated by the system, the salt value MUST be unique for each claim that is to be selectively
+//	disclosed.
+//	The claim name, or key, as it would be used in a regular JWT body. This MUST be a string.
+//	The claim's value, as it would be used in a regular JWT body. The value MAY be of any type that is allowed in JSON,
+//	including numbers, strings, booleans, arrays, and objects.
+//
+// Then JSON-encode the array such that an UTF-8 string is produced.
+// Then base64url-encode the byte representation of the UTF-8 string to create the Disclosure.
 func New(issuer string, claims interface{}, headers jose.Headers,
 	signer jose.Signer, opts ...NewOpt) (*SelectiveDisclosureJWT, error) {
 	nOpts := &newOpts{
@@ -223,7 +274,17 @@ func New(issuer string, claims interface{}, headers jose.Headers,
 	return &SelectiveDisclosureJWT{Disclosures: disclosures, SignedJWT: signedJWT}, nil
 }
 
-// NewFromVC creates new signed Selective Disclosure JWT based on vc.
+/*
+NewFromVC creates new signed Selective Disclosure JWT based on Verifiable Credential.
+
+Algorithm:
+  - extract credential subject map from verifiable credential
+  - create un-signed SD-JWT plus Disclosures with credential subject map
+  - decode claims from SD-JWT to get credential subject map with selective disclosures
+  - replace VC credential subject with newly created credential subject with selective disclosures
+  - create signed SD-JWT based on VC
+  - return signed SD-JWT plus Disclosures
+*/
 func NewFromVC(vc map[string]interface{}, headers jose.Headers,
 	signer jose.Signer, opts ...NewOpt) (*SelectiveDisclosureJWT, error) {
 	csObj, ok := common.GetKeyFromVC(credentialSubjectKey, vc)
diff --git a/pkg/doc/sdjwt/sdjwt-doc.go b/pkg/doc/sdjwt/sdjwt-doc.go
new file mode 100644
index 000000000..278d3c493
--- /dev/null
+++ b/pkg/doc/sdjwt/sdjwt-doc.go
@@ -0,0 +1,36 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+// Package sdjwt implements creating JSON Web Token (JWT) documents that support selective disclosure of JWT claims.
+//
+// In an SD-JWT, claims can be hidden, but cryptographically protected against undetected modification.
+//
+// When issuing the SD-JWT to the Holder, the Issuer also sends the cleartext counterparts of all hidden claims,
+// the so-called Disclosures, separate from the SD-JWT itself.
+//
+// The Holder decides which claims to disclose to a Verifier and forwards the respective Disclosures
+// together with the SD-JWT to the Verifier.
+//
+// The Verifier has to verify that all disclosed claim values were part of the original, Issuer-signed SD-JWT.
+// The Verifier will not, however, learn any claim values not disclosed in the Disclosures.
+//
+// This implementation supports:
+//
+// - selectively disclosable claims in flat data structures as well as more complex, nested data structures
+//
+// - combining selectively disclosable claims with clear-text claims that are always disclosed
+//
+// - options for specifying registered claim names that will be included in plaintext (e.g. iss, exp, or nbf)
+//
+// - option for configuring clear-text claims
+//
+// For selectively disclosable claims, claim names are always blinded.
+//
+// This implementation also supports an optional mechanism for Holder Binding,
+// the concept of binding an SD-JWT to key material controlled by the Holder.
+// The strength of the Holder Binding is conditional upon the trust in the protection
+// of the private key of the key pair an SD-JWT is bound to.
+package sdjwt
diff --git a/pkg/doc/sdjwt/verifier/example_test.go b/pkg/doc/sdjwt/verifier/example_test.go
new file mode 100644
index 000000000..98dceb6a2
--- /dev/null
+++ b/pkg/doc/sdjwt/verifier/example_test.go
@@ -0,0 +1,96 @@
+/*
+Copyright SecureKey Technologies Inc. All Rights Reserved.
+
+SPDX-License-Identifier: Apache-2.0
+*/
+
+package verifier
+
+import (
+	"crypto/ed25519"
+	"crypto/rand"
+	"encoding/json"
+	"fmt"
+
+	afjwt "github.com/hyperledger/aries-framework-go/pkg/doc/jwt"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/common"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/holder"
+	"github.com/hyperledger/aries-framework-go/pkg/doc/sdjwt/issuer"
+)
+
+func ExampleParse() {
+	signer, signatureVerifier, err := setUp()
+	if err != nil {
+		fmt.Println("failed to set-up test: %w", err.Error())
+	}
+
+	claims := map[string]interface{}{
+		"given_name": "Albert",
+		"last_name":  "Smith",
+	}
+
+	// Issuer will issue SD-JWT for specified claims.
+	token, err := issuer.New(testIssuer, claims, nil, signer)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	combinedFormatForIssuance, err := token.Serialize(false)
+	if err != nil {
+		fmt.Println("failed to issue SD-JWT: %w", err.Error())
+	}
+
+	// Holder will parse combined format for issuance for verification purposes.
+	_, err = holder.Parse(combinedFormatForIssuance, holder.WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("holder failed to parse SD-JWT: %w", err.Error())
+	}
+
+	// The Holder will disclose all claims.
+	combinedFormatForPresentation := combinedFormatForIssuance + common.CombinedFormatSeparator
+
+	// Verifier will validate combined format for presentation and create verified claims.
+	verifiedClaims, err := Parse(combinedFormatForPresentation,
+		WithSignatureVerifier(signatureVerifier))
+	if err != nil {
+		fmt.Println("verifier failed to parse holder presentation: %w", err.Error())
+	}
+
+	verifiedClaimsJSON, err := marshalObj(verifiedClaims)
+	if err != nil {
+		fmt.Println("verifier failed to marshal verified claims: %w", err.Error())
+	}
+
+	fmt.Println(verifiedClaimsJSON)
+
+	// Output: {
+	//	"given_name": "Albert",
+	//	"iss": "https://example.com/issuer",
+	//	"last_name": "Smith"
+	//}
+}
+
+func setUp() (*afjwt.JoseED25519Signer, *afjwt.JoseEd25519Verifier, error) {
+	issuerPublicKey, issuerPrivateKey, err := ed25519.GenerateKey(rand.Reader)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	signer := afjwt.NewEd25519Signer(issuerPrivateKey)
+
+	signatureVerifier, err := afjwt.NewEd25519Verifier(issuerPublicKey)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return signer, signatureVerifier, nil
+}
+
+func marshalObj(obj interface{}) (string, error) {
+	objBytes, err := json.Marshal(obj)
+	if err != nil {
+		fmt.Println("failed to marshal object: %w", err.Error())
+	}
+
+	return prettyPrint(objBytes)
+}
diff --git a/pkg/doc/sdjwt/verifier/verifier.go b/pkg/doc/sdjwt/verifier/verifier.go
index a8531e11c..7b83b4f8f 100644
--- a/pkg/doc/sdjwt/verifier/verifier.go
+++ b/pkg/doc/sdjwt/verifier/verifier.go
@@ -4,6 +4,10 @@ Copyright SecureKey Technologies Inc. All Rights Reserved.
 SPDX-License-Identifier: Apache-2.0
 */
 
+/*
+Package verifier enables the Verifier: An entity that requests, checks and
+extracts the claims from an SD-JWT and respective Disclosures.
+*/
 package verifier
 
 import (
@@ -45,7 +49,7 @@ func WithJWTDetachedPayload(payload []byte) ParseOpt {
 	}
 }
 
-// WithSignatureVerifier option is for definition of JWT detached payload.
+// WithSignatureVerifier option is for definition of signature verifier.
 func WithSignatureVerifier(signatureVerifier jose.SignatureVerifier) ParseOpt {
 	return func(opts *parseOpts) {
 		opts.sigVerifier = signatureVerifier
@@ -95,6 +99,20 @@ func WithLeewayForClaimsValidation(duration time.Duration) ParseOpt {
 }
 
 // Parse parses combined format for presentation and returns verified claims.
+// The Verifier has to verify that all disclosed claim values were part of the original, Issuer-signed SD-JWT.
+//
+// At a high level, the Verifier:
+//   - receives the Combined Format for Presentation from the Holder and verifies the signature of the SD-JWT using the
+//     Issuer's public key,
+//   - verifies the Holder Binding JWT, if Holder Binding is required by the Verifier's policy,
+//     using the public key included in the SD-JWT,
+//   - calculates the digests over the Holder-Selected Disclosures and verifies that each digest
+//     is contained in the SD-JWT.
+//
+// Detailed algorithm:
+// https://www.ietf.org/archive/id/draft-ietf-oauth-selective-disclosure-jwt-02.html#name-verification-by-the-verifier
+//
+// The Verifier will not, however, learn any claim values not disclosed in the Disclosures.
 func Parse(combinedFormatForPresentation string, opts ...ParseOpt) (map[string]interface{}, error) {
 	defaultSigningAlgorithms := []string{"EdDSA", "RS256"}
 	pOpts := &parseOpts{