openbadgeslib 3.1.1__tar.gz → 3.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/Changelog.txt +63 -0
  2. {openbadgeslib-3.1.1/openbadgeslib.egg-info → openbadgeslib-3.3.0}/PKG-INFO +84 -24
  3. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/README.md +80 -22
  4. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/baking.py +29 -5
  5. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/config.ini.example +4 -0
  6. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/confparser.py +19 -0
  7. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob1/badge.py +19 -0
  8. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/__init__.py +11 -1
  9. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/__init__.py +127 -0
  10. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/credentials-v2.json +340 -0
  11. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/ob-v3p0-context-3.0.1.json +447 -0
  12. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/ob-v3p0-context-3.0.2.json +431 -0
  13. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/ob-v3p0-context-3.0.3.json +452 -0
  14. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/security-data-integrity-v2.json +81 -0
  15. openbadgeslib-3.3.0/openbadgeslib/ob3/contexts/security-multikey-v1.json +35 -0
  16. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/credential.py +25 -6
  17. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/did.py +113 -2
  18. openbadgeslib-3.3.0/openbadgeslib/ob3/ldp.py +565 -0
  19. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/verifier.py +76 -34
  20. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/openbadges_signer.py +92 -12
  21. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/openbadges_verifier.py +40 -10
  22. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/util.py +1 -1
  23. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0/openbadgeslib.egg-info}/PKG-INFO +84 -24
  24. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib.egg-info/SOURCES.txt +20 -0
  25. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib.egg-info/requires.txt +3 -0
  26. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/pyproject.toml +11 -2
  27. openbadgeslib-3.3.0/tests/fixtures/vc_di_eddsa/README.md +13 -0
  28. openbadgeslib-3.3.0/tests/fixtures/vc_di_eddsa/credentials-examples-v2.json +5 -0
  29. openbadgeslib-3.3.0/tests/fixtures/vc_di_eddsa/doc-hash.txt +1 -0
  30. openbadgeslib-3.3.0/tests/fixtures/vc_di_eddsa/key-pair.json +4 -0
  31. openbadgeslib-3.3.0/tests/fixtures/vc_di_eddsa/proof-config-hash.txt +1 -0
  32. openbadgeslib-3.3.0/tests/fixtures/vc_di_eddsa/signed-credential.json +27 -0
  33. openbadgeslib-3.3.0/tests/ldp_helpers.py +55 -0
  34. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_confparser.py +25 -0
  35. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob1_badge_io.py +28 -0
  36. openbadgeslib-3.3.0/tests/test_ob3_contexts.py +76 -0
  37. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_credential.py +32 -0
  38. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_did.py +126 -0
  39. openbadgeslib-3.3.0/tests/test_ob3_ldp.py +292 -0
  40. openbadgeslib-3.3.0/tests/test_ob3_ldp_cli.py +166 -0
  41. openbadgeslib-3.3.0/tests/test_ob3_ldp_sign.py +292 -0
  42. openbadgeslib-3.3.0/tests/test_ob3_signer_cli_ldp.py +231 -0
  43. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/LICENSE.txt +0 -0
  44. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/MANIFEST.in +0 -0
  45. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/docs/README.md +0 -0
  46. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/__init__.py +0 -0
  47. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/_jws/__init__.py +0 -0
  48. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/_jws/exceptions.py +0 -0
  49. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/_jws/utils.py +0 -0
  50. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/badge.py +0 -0
  51. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/errors.py +0 -0
  52. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/keys.py +0 -0
  53. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/logs.py +0 -0
  54. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/mail.py +0 -0
  55. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob1/__init__.py +0 -0
  56. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob1/signer.py +0 -0
  57. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob1/verifier.py +0 -0
  58. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob2/__init__.py +0 -0
  59. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob2/models.py +0 -0
  60. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob2/signer.py +0 -0
  61. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob2/verifier.py +0 -0
  62. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/signer.py +0 -0
  63. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/status.py +0 -0
  64. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/status_list.py +0 -0
  65. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/ob3/status_registry.py +0 -0
  66. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/openbadges_init.py +0 -0
  67. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/openbadges_keygenerator.py +0 -0
  68. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/openbadges_publish.py +0 -0
  69. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/py.typed +0 -0
  70. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/signer.py +0 -0
  71. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib/verifier.py +0 -0
  72. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib.egg-info/dependency_links.txt +0 -0
  73. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib.egg-info/entry_points.txt +0 -0
  74. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/openbadgeslib.egg-info/top_level.txt +0 -0
  75. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/setup.cfg +0 -0
  76. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/config1.ini +0 -0
  77. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/conftest.py +0 -0
  78. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/images/sample1.png +0 -0
  79. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/images/sample1.svg +0 -0
  80. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/images/userimage01.svg +0 -0
  81. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/logo Python Espan/314/203a.svg" +0 -0
  82. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/logo Python Espa/303/261a.svg" +0 -0
  83. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/runtests.sh +0 -0
  84. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_cli_json.py +0 -0
  85. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_cli_smoke.py +0 -0
  86. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_docs.py +0 -0
  87. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_eddsa.py +0 -0
  88. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_jws.py +0 -0
  89. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_key_operation.py +0 -0
  90. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob1_signer.py +0 -0
  91. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob1_verifier.py +0 -0
  92. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob2_cli.py +0 -0
  93. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob2_models.py +0 -0
  94. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob2_signer.py +0 -0
  95. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob2_verifier.py +0 -0
  96. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_did_doc.py +0 -0
  97. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_publish_cli.py +0 -0
  98. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_signer.py +0 -0
  99. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_status.py +0 -0
  100. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_status_list.py +0 -0
  101. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_status_registry.py +0 -0
  102. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_ob3_verifier.py +0 -0
  103. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_sign_ecc.pem +0 -0
  104. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_sign_rsa.pem +0 -0
  105. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_util.py +0 -0
  106. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_verify_ecc.pem +0 -0
  107. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/test_verify_rsa.pem +0 -0
  108. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/withoutxmlheader.svg +0 -0
  109. {openbadgeslib-3.1.1 → openbadgeslib-3.3.0}/tests/withxmlheader.svg +0 -0
@@ -4,6 +4,69 @@ OpenBadgesLib - Changelog
4
4
  Newest first. Dates are ISO 8601 (YYYY-MM-DD).
5
5
 
6
6
 
7
+ * v3.3.0 - 2026-07-04
8
+
9
+ - feat(ob3): issuance of OB 3.0 credentials secured with a W3C Data
10
+ Integrity proof (eddsa-rdfc-2022) — new `OB3LdpSigner` and low-level
11
+ `add_data_integrity_proof`, the signing counterparts of the verifiers
12
+ shipped in 3.2.0, sharing their canonicalization core and reproducing
13
+ the official W3C vc-di-eddsa test vector byte for byte. Ed25519 keys
14
+ only; requires the `[ldp]` extra, which now covers both directions.
15
+
16
+ - feat(cli): `openbadges-signer -P/--proof-format {vc-jwt,ldp}` (OB3
17
+ only) plus an optional per-badge `proof_format` config key (flag wins;
18
+ default vc-jwt). With `[issuer] did` configured the proof names the
19
+ `did:web:...#badge_N` verification method `openbadges-publish -V 3`
20
+ publishes (trusted via `--resolve-did`); otherwise it falls back to a
21
+ self-asserted did:key derived from the signing key and tells the
22
+ operator so. LDP-signed badges are tagged `PROOF ldp` in the signer
23
+ audit log. Status lists stay VC-JWT regardless of the badge's proof
24
+ format.
25
+
26
+ - feat(ob3): multikey/did:key encoders in `ob3.did` —
27
+ `multikey_from_pem` (publicKeyMultibase) and `did_key_from_pem`,
28
+ the exact inverses of the resolvers, for Ed25519 and NIST P-256.
29
+
30
+ - fix(cli): `Badge.create_from_conf` rejected `key_type = ED25519`
31
+ outright, so the CLI could never sign with the keys
32
+ `openbadges-keygenerator -t ED25519` produces; Ed25519 key material
33
+ now loads, and the legacy OB 1.0 path (`-V 1`) refuses non-RSA/ECC
34
+ keys with a clean message instead of failing mid-JWS.
35
+
36
+
37
+ * v3.2.0 - 2026-07-03
38
+
39
+ - feat(ob3): verification of OB 3.0 credentials secured with a W3C Data
40
+ Integrity proof (the Linked Data Proof format), cryptosuite
41
+ eddsa-rdfc-2022 — new `OB3LdpVerifier` and low-level
42
+ `verify_data_integrity_proof`, validated against the official W3C
43
+ vc-di-eddsa test vectors. Verify-only: issuing stays JWT-VC. Requires
44
+ the new optional extra: `pip install "openbadgeslib[ldp]"` (pyld);
45
+ everything else works without it.
46
+
47
+ - feat(ob3): JSON-LD @context documents are never fetched from the
48
+ network — the exact context files ship pinned inside the wheel behind
49
+ an exact-match allowlist (fail-closed on unknown contexts), and Data
50
+ Integrity documents are capped at 256 KiB before canonicalization.
51
+
52
+ - feat(ob3): `resolve_verification_method` resolves the exact
53
+ verificationMethod URL a proof names (did:key fragment validation;
54
+ did:web entry selected by id, fail-closed on no match).
55
+
56
+ - feat(baking): OB 3.0 §5.3 text-content carrier for Data Integrity
57
+ credentials — `bake_svg(..., as_text=True)` and an opt-in
58
+ `extract_svg(..., text_fallback=True)`; the OB3 extraction returns
59
+ either a compact JWT or the credential JSON. PNG needed no change.
60
+
61
+ - feat(cli): `openbadges-verifier -V 3` autodetects the baked payload
62
+ (JWT-VC vs Data Integrity) with the same trust flags, reports
63
+ `proof_format` in `--json`, and hints at the missing `[ldp]` extra.
64
+
65
+ - feat(api): `OpenBadgeCredential.from_vc_document` reconstructs a
66
+ credential from its JSON-LD document shape (same validation as the
67
+ JWT payload path).
68
+
69
+
7
70
  * v3.1.1 - 2026-07-03
8
71
 
9
72
  - docs(packaging): discoverability metadata — a descriptive PyPI summary,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openbadgeslib
3
- Version: 3.1.1
3
+ Version: 3.3.0
4
4
  Summary: Production-ready Python library & CLI for Open Badges 3.0 (W3C Verifiable Credentials): issue, verify, and revoke JWT-VC credentials with Bitstring Status Lists and did:web — plus strict OB 2.0 and legacy OB 1.0.
5
5
  Author-email: Luis González Fernández <luisgf@luisgf.es>, Jesús Cea Avión <jcea@jcea.es>
6
6
  License: LGPLv3
@@ -9,7 +9,7 @@ Project-URL: Documentation, https://github.com/luisgf/openbadgeslib/wiki
9
9
  Project-URL: API Reference, https://luisgf.github.io/openbadgeslib/
10
10
  Project-URL: Source, https://github.com/luisgf/openbadgeslib
11
11
  Project-URL: Changelog, https://github.com/luisgf/openbadgeslib/blob/master/Changelog.txt
12
- Keywords: openbadges,open-badges,verifiable-credentials,vc-jwt,w3c-vc,digital-credentials,did,did-web,bitstring-status-list,revocation,ob3,credentials,ed25519,cryptography
12
+ Keywords: openbadges,open-badges,verifiable-credentials,vc-jwt,w3c-vc,digital-credentials,did,did-web,bitstring-status-list,revocation,ob3,credentials,ed25519,cryptography,data-integrity,eddsa
13
13
  Classifier: Development Status :: 5 - Production/Stable
14
14
  Classifier: Intended Audience :: Developers
15
15
  Classifier: Intended Audience :: Education
@@ -34,6 +34,8 @@ Requires-Dist: pypng>=0.20220715.0
34
34
  Requires-Dist: PyJWT[crypto]>=2.8
35
35
  Requires-Dist: cryptography>=42
36
36
  Requires-Dist: defusedxml>=0.7
37
+ Provides-Extra: ldp
38
+ Requires-Dist: pyld>=2.0.4; extra == "ldp"
37
39
  Provides-Extra: dev
38
40
  Requires-Dist: pytest>=8.0; extra == "dev"
39
41
  Requires-Dist: pytest-cov>=5.0; extra == "dev"
@@ -52,7 +54,8 @@ Dynamic: license-file
52
54
 
53
55
  **A production-ready Python library & CLI for the full Open Badges 3.0 issuer
54
56
  lifecycle** — issue [W3C Verifiable Credentials](https://www.w3.org/TR/vc-data-model-2.0/)
55
- as JWT-VC, bake them into SVG/PNG, verify them, and **revoke or suspend** them
57
+ as JWT-VC or W3C Data Integrity (LDP) proofs, bake them into SVG/PNG, verify them,
58
+ and **revoke or suspend** them
56
59
  with W3C Bitstring Status Lists and `did:web`. It also ships strict
57
60
  **OpenBadges 2.0** (JWS / hosted assertions) and a frozen **OpenBadges 1.0**
58
61
  legacy format, selected with `-V {1,2,3}` (default `3`).
@@ -61,12 +64,14 @@ legacy format, selected with `-V {1,2,3}` (default `3`).
61
64
 
62
65
  - Sign badge images (SVG and PNG) as strict OB 2.0 JWS / hosted assertions (with a frozen OB 1.0 legacy format)
63
66
  - Issue and verify OpenBadges 3.0 JWT-VC credentials
64
- - Bake OB 3.0 JWT tokens into SVG and PNG badge images
67
+ - Bake OB 3.0 credentials (JWT-VC or Data Integrity JSON-LD) into SVG and PNG badge images
65
68
  - RSA 2048-bit (RS256), ECC NIST P-256 (ES256), and Ed25519 (EdDSA) key support
66
69
  - SHA-256 hashed recipient identity with salt (OB 2.0)
67
70
  - Expiration and revocation checking
68
71
  - Issuer-side OB 3.0 revocation and suspension: W3C Bitstring Status List
69
72
  publication and `--revoke` / `--suspend` / `--unsuspend` management
73
+ - Issue and verify OB 3.0 W3C Data Integrity credentials (`eddsa-rdfc-2022`,
74
+ optional `[ldp]` extra) in addition to JWT-VC
70
75
  - did:web issuer identity: `did.json` generation and DID resolution
71
76
  - Five command-line tools included
72
77
 
@@ -75,8 +80,10 @@ legacy format, selected with `-V {1,2,3}` (default `3`).
75
80
  - **The complete OB 3.0 issuer lifecycle in Python** — not just issuing, but
76
81
  publishing trust artefacts (`did:web`) and revoking/suspending credentials via
77
82
  Bitstring Status Lists, driven from the CLI or the library.
78
- - **Native VC-JWT** signing with RSA (RS256), ECC P-256 (ES256) and Ed25519
79
- (EdDSA), and offline verification.
83
+ - **Native VC-JWT signing** with RSA (RS256), ECC P-256 (ES256) and Ed25519
84
+ (EdDSA) *plus* native **W3C Data Integrity / LDP** signing
85
+ (`eddsa-rdfc-2022`, Ed25519, optional `[ldp]` extra). Both proof formats
86
+ issue *and* verify offline, no external service.
80
87
  - **Lean and typed** — `mypy --strict`, CI on Python 3.10–3.13, a small
81
88
  dependency set, dataclasses + explicit validation (no Pydantic).
82
89
  - **Dual-licensed** LGPLv3 (library) / BSD-2-Clause (CLI tools).
@@ -84,23 +91,39 @@ legacy format, selected with `-V {1,2,3}` (default `3`).
84
91
  ### How it compares
85
92
 
86
93
  Best-effort comparison from each project's public documentation as of July 2026;
87
- "not documented" is shown as `—`. Corrections welcome via issue/PR.
88
-
89
- | Capability | **openbadgeslib** | [PyOpenBadges](https://github.com/CoopCodeCommun/pyopenbadges) |
90
- | --- | --- | --- |
91
- | Open Badges versions | 1.0, 2.0, **3.0** | 3.0 (v2→v3 planned) |
92
- | OB 3.0 proof: VC-JWT (JOSE) | ✅ RS/ES/EdDSA | roadmap |
93
- | OB 3.0 proof: Data Integrity / LDP | — (verify-first, planned) | JSON-LD signing (format unspecified) |
94
- | Revocation / suspension (Bitstring Status List) | issue + publish + manage | |
95
- | `did:web` (generate + resolve) | | |
96
- | Image baking (SVG + PNG) | | roadmap |
97
- | Command-line tools | ✅ 5 tools | |
98
- | Typing / CI | `mypy --strict`, CI 3.10–3.13 | — |
99
- | Validation | dataclasses + explicit checks | Pydantic |
100
-
101
- For OB 2.0 validation the reference implementation is 1EdTech's Node
102
- [`openbadges-validator`](https://github.com/1EdTech/openbadges-validator); this
103
- table focuses on the OB 3.0 Python landscape.
94
+ "not documented" is shown as `—`. Corrections welcome via issue/PR. The Python
95
+ Open Badges landscape splits into three groups: 1EdTech's **verify-only** OB 2.0
96
+ reference validator, heavyweight **Django server platforms** (the Badgr lineage),
97
+ and a thin tail of **standalone libraries** — of which openbadgeslib is the only
98
+ actively-maintained, pip-installable, offline one that covers all three OB
99
+ versions and both OB 3.0 proof formats.
100
+
101
+ | Capability | **openbadgeslib** | [validator-core](https://github.com/1EdTech/openbadges-validator-core) | [Badgr / mint-o-badges](https://github.com/mint-o-badges/badgr-server) (a) | [pyopenbadges](https://github.com/CoopCodeCommun/pyopenbadges) | [didkit](https://github.com/spruceid/didkit-python) (b) |
102
+ | --- | --- | --- | --- | --- | --- |
103
+ | Open Badges versions | 1.0, 2.0, **3.0** | 0.5–2.0 | 1.1, 2.0, 3.0 | 3.0 only | generic VC |
104
+ | Issue / verify | ✅ both | verify only | issue; partial verify | both | both (VC + VP) |
105
+ | OB 3.0 proof: VC-JWT (JOSE) | RS/ES/EdDSA | | — | roadmap | ✅ not OB-aware |
106
+ | OB 3.0 proof: Data Integrity / LDP | issue + verify (`eddsa-rdfc-2022`) | | issue only (Ed25519) | home-grown, non-conformant | older suites; no `rdfc-2022` in wheel |
107
+ | Revocation / suspension | ✅ W3C Bitstring Status List | hosted check | `1EdTechRevocationList` | ad-hoc flag | — |
108
+ | `did:web` (generate + resolve) | | | — | — | resolve only |
109
+ | Image baking (SVG + PNG) | ✅ | unbake only | ✅ | — | — |
110
+ | Form factor | library + 5 CLI tools | library + CLI | Django server | library | binding |
111
+ | Typing / CI | `mypy --strict`, CI 3.10–3.13 | — | — | Pydantic | — |
112
+ | License | LGPLv3 / BSD-2 | Apache-2.0 | AGPL-3.0 | MIT/LGPL | Apache-2.0 |
113
+
114
+ (a) The actively-maintained community fork (open-educational-badges): it
115
+ genuinely issues OB 3.0 Data Integrity credentials, but only as a server (not a
116
+ pip library) and only with Ed25519 (no VC-JWT). The classic Concentric Sky
117
+ `badgr-server` is OB 2.0 and its canonical repo is gone; SURF's
118
+ `edubadges-server` delegates OB 3.0 signing to external agents.
119
+ (b) Generic W3C VC/DID toolkit (Rust `ssi` bindings), not Open Badges-aware, and
120
+ archived (read-only since July 2025).
121
+
122
+ For authoritative OB 2.0 *validation* semantics, 1EdTech's Python
123
+ [`openbadges-validator-core`](https://github.com/1EdTech/openbadges-validator-core)
124
+ and Node [`openbadges-validator`](https://github.com/1EdTech/openbadges-validator)
125
+ remain the reference; openbadgeslib focuses on the full issuer lifecycle across
126
+ all three OB versions.
104
127
 
105
128
  ## Requirements
106
129
 
@@ -187,7 +210,15 @@ with open('/tmp/signed_badge.svg', 'wb') as f:
187
210
 
188
211
  For the frozen OpenBadges 1.0 legacy API (`Badge` / `Signer` / `Verifier`), import from `openbadgeslib.ob1` instead.
189
212
 
190
- ## Using the library — OpenBadges 3.0 (JWT-VC)
213
+ ## Using the library — OpenBadges 3.0
214
+
215
+ OB 3.0 credentials can be secured with either of the two proof formats the
216
+ spec allows: a compact **VC-JWT** (`OB3Signer`, RS256/ES256/EdDSA) or an
217
+ embedded **Data Integrity** proof (`OB3LdpSigner`, cryptosuite
218
+ `eddsa-rdfc-2022`, Ed25519 only — needs the `[ldp]` extra). Both bake into
219
+ the same SVG/PNG carriers and the verifier auto-detects the format.
220
+
221
+ ### VC-JWT (JOSE)
191
222
 
192
223
  ```python
193
224
  from openbadgeslib.ob3 import (
@@ -223,6 +254,35 @@ restored = verifier.verify(token, expected_recipient='recipient@example.com')
223
254
  print('Recipient:', restored.recipient_id)
224
255
  ```
225
256
 
257
+ ### Data Integrity (LDP)
258
+
259
+ Same credential, an embedded JSON-LD proof instead of a JWT. Requires an
260
+ Ed25519 signing key and the `[ldp]` extra (`pip install openbadgeslib[ldp]`).
261
+ Reuse the `credential` built above:
262
+
263
+ ```python
264
+ from openbadgeslib.ob3 import OB3LdpSigner, OB3LdpVerifier
265
+
266
+ with open('sign_ed25519.pem', 'rb') as f:
267
+ priv_pem = f.read()
268
+
269
+ # Bake a credential carrying an eddsa-rdfc-2022 DataIntegrityProof into an SVG
270
+ signer = OB3LdpSigner(priv_pem)
271
+ with open('badge.svg', 'rb') as f:
272
+ baked_svg = signer.sign_into_svg(credential, f.read())
273
+
274
+ # Verify (the LDP credential travels as JSON in the baked image)
275
+ with open('verify_ed25519.pem', 'rb') as f:
276
+ verifier = OB3LdpVerifier(pubkey_pem=f.read())
277
+ document = OB3Verifier.extract_token_from_svg(baked_svg)
278
+ restored = verifier.verify(document, expected_recipient='recipient@example.com')
279
+ print('Recipient:', restored.recipient_id)
280
+ ```
281
+
282
+ From the CLI, select the format with `openbadges-signer -P ldp` (OB 3.0 only),
283
+ or set `proof_format = ldp` in the badge's INI section; the default stays
284
+ `vc-jwt`. Status lists remain VC-JWT regardless of the badge's proof format.
285
+
226
286
  ## Documentation
227
287
 
228
288
  - **User & developer guide** — the project [**Wiki**](https://github.com/luisgf/openbadgeslib/wiki):
@@ -7,7 +7,8 @@
7
7
 
8
8
  **A production-ready Python library & CLI for the full Open Badges 3.0 issuer
9
9
  lifecycle** — issue [W3C Verifiable Credentials](https://www.w3.org/TR/vc-data-model-2.0/)
10
- as JWT-VC, bake them into SVG/PNG, verify them, and **revoke or suspend** them
10
+ as JWT-VC or W3C Data Integrity (LDP) proofs, bake them into SVG/PNG, verify them,
11
+ and **revoke or suspend** them
11
12
  with W3C Bitstring Status Lists and `did:web`. It also ships strict
12
13
  **OpenBadges 2.0** (JWS / hosted assertions) and a frozen **OpenBadges 1.0**
13
14
  legacy format, selected with `-V {1,2,3}` (default `3`).
@@ -16,12 +17,14 @@ legacy format, selected with `-V {1,2,3}` (default `3`).
16
17
 
17
18
  - Sign badge images (SVG and PNG) as strict OB 2.0 JWS / hosted assertions (with a frozen OB 1.0 legacy format)
18
19
  - Issue and verify OpenBadges 3.0 JWT-VC credentials
19
- - Bake OB 3.0 JWT tokens into SVG and PNG badge images
20
+ - Bake OB 3.0 credentials (JWT-VC or Data Integrity JSON-LD) into SVG and PNG badge images
20
21
  - RSA 2048-bit (RS256), ECC NIST P-256 (ES256), and Ed25519 (EdDSA) key support
21
22
  - SHA-256 hashed recipient identity with salt (OB 2.0)
22
23
  - Expiration and revocation checking
23
24
  - Issuer-side OB 3.0 revocation and suspension: W3C Bitstring Status List
24
25
  publication and `--revoke` / `--suspend` / `--unsuspend` management
26
+ - Issue and verify OB 3.0 W3C Data Integrity credentials (`eddsa-rdfc-2022`,
27
+ optional `[ldp]` extra) in addition to JWT-VC
25
28
  - did:web issuer identity: `did.json` generation and DID resolution
26
29
  - Five command-line tools included
27
30
 
@@ -30,8 +33,10 @@ legacy format, selected with `-V {1,2,3}` (default `3`).
30
33
  - **The complete OB 3.0 issuer lifecycle in Python** — not just issuing, but
31
34
  publishing trust artefacts (`did:web`) and revoking/suspending credentials via
32
35
  Bitstring Status Lists, driven from the CLI or the library.
33
- - **Native VC-JWT** signing with RSA (RS256), ECC P-256 (ES256) and Ed25519
34
- (EdDSA), and offline verification.
36
+ - **Native VC-JWT signing** with RSA (RS256), ECC P-256 (ES256) and Ed25519
37
+ (EdDSA) *plus* native **W3C Data Integrity / LDP** signing
38
+ (`eddsa-rdfc-2022`, Ed25519, optional `[ldp]` extra). Both proof formats
39
+ issue *and* verify offline, no external service.
35
40
  - **Lean and typed** — `mypy --strict`, CI on Python 3.10–3.13, a small
36
41
  dependency set, dataclasses + explicit validation (no Pydantic).
37
42
  - **Dual-licensed** LGPLv3 (library) / BSD-2-Clause (CLI tools).
@@ -39,23 +44,39 @@ legacy format, selected with `-V {1,2,3}` (default `3`).
39
44
  ### How it compares
40
45
 
41
46
  Best-effort comparison from each project's public documentation as of July 2026;
42
- "not documented" is shown as `—`. Corrections welcome via issue/PR.
43
-
44
- | Capability | **openbadgeslib** | [PyOpenBadges](https://github.com/CoopCodeCommun/pyopenbadges) |
45
- | --- | --- | --- |
46
- | Open Badges versions | 1.0, 2.0, **3.0** | 3.0 (v2→v3 planned) |
47
- | OB 3.0 proof: VC-JWT (JOSE) | ✅ RS/ES/EdDSA | roadmap |
48
- | OB 3.0 proof: Data Integrity / LDP | — (verify-first, planned) | JSON-LD signing (format unspecified) |
49
- | Revocation / suspension (Bitstring Status List) | issue + publish + manage | |
50
- | `did:web` (generate + resolve) | | |
51
- | Image baking (SVG + PNG) | | roadmap |
52
- | Command-line tools | ✅ 5 tools | |
53
- | Typing / CI | `mypy --strict`, CI 3.10–3.13 | — |
54
- | Validation | dataclasses + explicit checks | Pydantic |
55
-
56
- For OB 2.0 validation the reference implementation is 1EdTech's Node
57
- [`openbadges-validator`](https://github.com/1EdTech/openbadges-validator); this
58
- table focuses on the OB 3.0 Python landscape.
47
+ "not documented" is shown as `—`. Corrections welcome via issue/PR. The Python
48
+ Open Badges landscape splits into three groups: 1EdTech's **verify-only** OB 2.0
49
+ reference validator, heavyweight **Django server platforms** (the Badgr lineage),
50
+ and a thin tail of **standalone libraries** — of which openbadgeslib is the only
51
+ actively-maintained, pip-installable, offline one that covers all three OB
52
+ versions and both OB 3.0 proof formats.
53
+
54
+ | Capability | **openbadgeslib** | [validator-core](https://github.com/1EdTech/openbadges-validator-core) | [Badgr / mint-o-badges](https://github.com/mint-o-badges/badgr-server) (a) | [pyopenbadges](https://github.com/CoopCodeCommun/pyopenbadges) | [didkit](https://github.com/spruceid/didkit-python) (b) |
55
+ | --- | --- | --- | --- | --- | --- |
56
+ | Open Badges versions | 1.0, 2.0, **3.0** | 0.5–2.0 | 1.1, 2.0, 3.0 | 3.0 only | generic VC |
57
+ | Issue / verify | ✅ both | verify only | issue; partial verify | both | both (VC + VP) |
58
+ | OB 3.0 proof: VC-JWT (JOSE) | RS/ES/EdDSA | | — | roadmap | ✅ not OB-aware |
59
+ | OB 3.0 proof: Data Integrity / LDP | issue + verify (`eddsa-rdfc-2022`) | | issue only (Ed25519) | home-grown, non-conformant | older suites; no `rdfc-2022` in wheel |
60
+ | Revocation / suspension | ✅ W3C Bitstring Status List | hosted check | `1EdTechRevocationList` | ad-hoc flag | — |
61
+ | `did:web` (generate + resolve) | | | — | — | resolve only |
62
+ | Image baking (SVG + PNG) | ✅ | unbake only | ✅ | — | — |
63
+ | Form factor | library + 5 CLI tools | library + CLI | Django server | library | binding |
64
+ | Typing / CI | `mypy --strict`, CI 3.10–3.13 | — | — | Pydantic | — |
65
+ | License | LGPLv3 / BSD-2 | Apache-2.0 | AGPL-3.0 | MIT/LGPL | Apache-2.0 |
66
+
67
+ (a) The actively-maintained community fork (open-educational-badges): it
68
+ genuinely issues OB 3.0 Data Integrity credentials, but only as a server (not a
69
+ pip library) and only with Ed25519 (no VC-JWT). The classic Concentric Sky
70
+ `badgr-server` is OB 2.0 and its canonical repo is gone; SURF's
71
+ `edubadges-server` delegates OB 3.0 signing to external agents.
72
+ (b) Generic W3C VC/DID toolkit (Rust `ssi` bindings), not Open Badges-aware, and
73
+ archived (read-only since July 2025).
74
+
75
+ For authoritative OB 2.0 *validation* semantics, 1EdTech's Python
76
+ [`openbadges-validator-core`](https://github.com/1EdTech/openbadges-validator-core)
77
+ and Node [`openbadges-validator`](https://github.com/1EdTech/openbadges-validator)
78
+ remain the reference; openbadgeslib focuses on the full issuer lifecycle across
79
+ all three OB versions.
59
80
 
60
81
  ## Requirements
61
82
 
@@ -142,7 +163,15 @@ with open('/tmp/signed_badge.svg', 'wb') as f:
142
163
 
143
164
  For the frozen OpenBadges 1.0 legacy API (`Badge` / `Signer` / `Verifier`), import from `openbadgeslib.ob1` instead.
144
165
 
145
- ## Using the library — OpenBadges 3.0 (JWT-VC)
166
+ ## Using the library — OpenBadges 3.0
167
+
168
+ OB 3.0 credentials can be secured with either of the two proof formats the
169
+ spec allows: a compact **VC-JWT** (`OB3Signer`, RS256/ES256/EdDSA) or an
170
+ embedded **Data Integrity** proof (`OB3LdpSigner`, cryptosuite
171
+ `eddsa-rdfc-2022`, Ed25519 only — needs the `[ldp]` extra). Both bake into
172
+ the same SVG/PNG carriers and the verifier auto-detects the format.
173
+
174
+ ### VC-JWT (JOSE)
146
175
 
147
176
  ```python
148
177
  from openbadgeslib.ob3 import (
@@ -178,6 +207,35 @@ restored = verifier.verify(token, expected_recipient='recipient@example.com')
178
207
  print('Recipient:', restored.recipient_id)
179
208
  ```
180
209
 
210
+ ### Data Integrity (LDP)
211
+
212
+ Same credential, an embedded JSON-LD proof instead of a JWT. Requires an
213
+ Ed25519 signing key and the `[ldp]` extra (`pip install openbadgeslib[ldp]`).
214
+ Reuse the `credential` built above:
215
+
216
+ ```python
217
+ from openbadgeslib.ob3 import OB3LdpSigner, OB3LdpVerifier
218
+
219
+ with open('sign_ed25519.pem', 'rb') as f:
220
+ priv_pem = f.read()
221
+
222
+ # Bake a credential carrying an eddsa-rdfc-2022 DataIntegrityProof into an SVG
223
+ signer = OB3LdpSigner(priv_pem)
224
+ with open('badge.svg', 'rb') as f:
225
+ baked_svg = signer.sign_into_svg(credential, f.read())
226
+
227
+ # Verify (the LDP credential travels as JSON in the baked image)
228
+ with open('verify_ed25519.pem', 'rb') as f:
229
+ verifier = OB3LdpVerifier(pubkey_pem=f.read())
230
+ document = OB3Verifier.extract_token_from_svg(baked_svg)
231
+ restored = verifier.verify(document, expected_recipient='recipient@example.com')
232
+ print('Recipient:', restored.recipient_id)
233
+ ```
234
+
235
+ From the CLI, select the format with `openbadges-signer -P ldp` (OB 3.0 only),
236
+ or set `proof_format = ldp` in the badge's INI section; the default stays
237
+ `vc-jwt`. Status lists remain VC-JWT regardless of the badge's proof format.
238
+
181
239
  ## Documentation
182
240
 
183
241
  - **User & developer guide** — the project [**Wiki**](https://github.com/luisgf/openbadgeslib/wiki):
@@ -75,16 +75,26 @@ def _bounded_inflate(data: bytes, limit: int = MAX_ITXT_DECOMPRESSED) -> bytes:
75
75
  # ── SVG ─────────────────────────────────────────────────────────────────────
76
76
 
77
77
  def bake_svg(image_bytes: bytes, token: str, comment: Optional[str] = None, *,
78
- element: str = SVG_ELEMENT, namespace: str = SVG_NS) -> bytes:
78
+ element: str = SVG_ELEMENT, namespace: str = SVG_NS,
79
+ as_text: bool = False) -> bytes:
79
80
  """Return *image_bytes* with an ``<element verify=token>`` node (and an
80
81
  optional XML comment) appended to the root ``<svg>``. *element*/*namespace*
81
- default to the OB 2.0 identifiers; OB 3.0 passes its own."""
82
+ default to the OB 2.0 identifiers; OB 3.0 passes its own.
83
+
84
+ With ``as_text=True`` the token is stored as the element's text content
85
+ instead of the ``verify`` attribute — the OB 3.0 carrier for credentials
86
+ secured with a Data Integrity proof, whose payload is a JSON document
87
+ rather than a compact JWT (OB 3.0 §5.3).
88
+ """
82
89
  svg_doc = parseString(image_bytes)
83
90
  try:
84
91
  svg_tag = svg_doc.getElementsByTagName('svg').item(0)
85
92
  node = svg_doc.createElement(element)
86
93
  node.attributes['xmlns:openbadges'] = namespace
87
- node.attributes['verify'] = token
94
+ if as_text:
95
+ node.appendChild(svg_doc.createTextNode(token))
96
+ else:
97
+ node.attributes['verify'] = token
88
98
  svg_tag.appendChild(node)
89
99
  if comment:
90
100
  svg_tag.appendChild(svg_doc.createComment(comment))
@@ -102,12 +112,18 @@ def has_svg(image_bytes: bytes, *, element: str = SVG_ELEMENT) -> bool:
102
112
  svg_doc.unlink()
103
113
 
104
114
 
105
- def extract_svg(image_bytes: bytes, *, element: str = SVG_ELEMENT) -> Optional[str]:
115
+ def extract_svg(image_bytes: bytes, *, element: str = SVG_ELEMENT,
116
+ text_fallback: bool = False) -> Optional[str]:
106
117
  """Return the embedded token string, or None if the badge carries no token.
107
118
 
108
119
  None covers both a missing *element* node and a present element with no
109
120
  ``verify`` attribute (a well-formed SVG that simply isn't a signed badge).
110
121
  Malformed XML still raises (left to the caller to map to its own error type).
122
+
123
+ With ``text_fallback=True``, an element without a ``verify`` attribute
124
+ falls back to its text content — where OB 3.0 §5.3 bakes a credential
125
+ secured with a Data Integrity proof (a JSON document, not a compact JWT).
126
+ An empty/whitespace-only text content still yields None.
111
127
  """
112
128
  svg_doc = None
113
129
  try:
@@ -116,7 +132,15 @@ def extract_svg(image_bytes: bytes, *, element: str = SVG_ELEMENT) -> Optional[s
116
132
  if not nodes:
117
133
  return None
118
134
  attrs = nodes[0].attributes
119
- return attrs['verify'].nodeValue if 'verify' in attrs else None
135
+ if 'verify' in attrs:
136
+ return attrs['verify'].nodeValue
137
+ if not text_fallback:
138
+ return None
139
+ text = ''.join(
140
+ child.data for child in nodes[0].childNodes
141
+ if child.nodeType in (child.TEXT_NODE, child.CDATA_SECTION_NODE)
142
+ ).strip()
143
+ return text or None
120
144
  finally:
121
145
  if svg_doc is not None:
122
146
  svg_doc.unlink()
@@ -58,6 +58,10 @@ private_key = ${paths:base_key}/sign_rsa_key_1.pem
58
58
  public_key = ${paths:base_key}/verify_rsa_key_1.pem
59
59
  ; key_type selects the algorithm for openbadges-keygenerator: RSA (default), ECC, or ED25519
60
60
  key_type = RSA
61
+ ; OpenBadges 3.0 proof format: vc-jwt (compact JWT-VC, the default) or ldp
62
+ ; (embedded W3C Data Integrity proof, cryptosuite eddsa-rdfc-2022). ldp needs
63
+ ; key_type = ED25519 and the [ldp] extra (pip install openbadgeslib[ldp]).
64
+ ;proof_format = vc-jwt
61
65
  ; OpenBadges 3.0 credential status (opt-in). When set, openbadges-signer -V 3
62
66
  ; attaches credentialStatus entries for these purposes (comma-separated subset
63
67
  ; of: revocation, suspension) and openbadges-publish -V 3 generates the signed
@@ -79,6 +79,25 @@ def ob3_issuer_id(conf: ConfigParser) -> str:
79
79
  "[issuer] did must be 'auto' or a did:... identifier, got %r" % did)
80
80
 
81
81
 
82
+ #: Proof formats an OB3 credential can be issued with — the same vocabulary
83
+ #: openbadges-verifier reports in its JSON output.
84
+ OB3_PROOF_FORMATS = ('vc-jwt', 'ldp')
85
+
86
+
87
+ def ob3_proof_format(conf: ConfigParser, badge_section: str) -> str:
88
+ """Return the proof format OB3 credentials of *badge_section* use:
89
+ ``vc-jwt`` (compact JWT-VC, the default) or ``ldp`` (embedded Data
90
+ Integrity proof, cryptosuite eddsa-rdfc-2022 — needs an Ed25519 key and
91
+ the [ldp] extra). Raises ValueError for anything else.
92
+ """
93
+ value = (conf[badge_section].get('proof_format') or 'vc-jwt').strip()
94
+ if value in OB3_PROOF_FORMATS:
95
+ return value
96
+ raise ValueError(
97
+ "[%s] proof_format must be one of %s, got %r"
98
+ % (badge_section, ', '.join(OB3_PROOF_FORMATS), value))
99
+
100
+
82
101
  @dataclass
83
102
  class OB3StatusConfig:
84
103
  """Resolved per-badge OB3 credential status configuration."""
@@ -145,6 +145,25 @@ class Badge():
145
145
  self.priv_key = SigningKey.from_pem(self.privkey_pem)
146
146
  except Exception as exc:
147
147
  raise PrivateKeyReadError('Unable to read ECC private key: %s' % exc) from exc
148
+ elif self.key_type is KeyType.ED25519:
149
+ from cryptography.hazmat.primitives.serialization import (
150
+ load_pem_private_key, load_pem_public_key)
151
+ if self.pubkey_pem:
152
+ try:
153
+ pub_pem = self.pubkey_pem.encode('utf-8') \
154
+ if isinstance(self.pubkey_pem, str) else self.pubkey_pem
155
+ self.pub_key = load_pem_public_key(pub_pem)
156
+ except Exception as exc:
157
+ raise PublicKeyReadError(
158
+ 'Unable to read Ed25519 public key: %s' % exc) from exc
159
+ if self.privkey_pem:
160
+ try:
161
+ priv_pem = self.privkey_pem.encode('utf-8') \
162
+ if isinstance(self.privkey_pem, str) else self.privkey_pem
163
+ self.priv_key = load_pem_private_key(priv_pem, password=None)
164
+ except Exception as exc:
165
+ raise PrivateKeyReadError(
166
+ 'Unable to read Ed25519 private key: %s' % exc) from exc
148
167
  elif self.key_type is not None:
149
168
  # key_type=None is a valid "no key material yet" state; any other
150
169
  # value is an unsupported key type and must fail loudly.
@@ -23,26 +23,36 @@
23
23
  from .credential import Achievement, Issuer, OpenBadgeCredential
24
24
  from .signer import OB3Signer
25
25
  from .verifier import OB3VerificationError, OB3Verifier
26
+ from .ldp import (OB3LdpSigner, OB3LdpVerifier, add_data_integrity_proof,
27
+ verify_data_integrity_proof)
26
28
  from .status import check_credential_status
27
29
  from .status_list import (build_status_list_credential, encode_bitstring,
28
30
  sign_status_list_credential, status_entry)
29
31
  from .status_registry import StatusRegistry
30
- from .did import build_did_document, did_web_from_url, resolve_did
32
+ from .did import (build_did_document, did_key_from_pem, did_web_from_url,
33
+ multikey_from_pem, resolve_did, resolve_verification_method)
31
34
 
32
35
  __all__ = [
33
36
  'Achievement',
34
37
  'Issuer',
35
38
  'OpenBadgeCredential',
39
+ 'OB3LdpSigner',
40
+ 'OB3LdpVerifier',
36
41
  'OB3Signer',
37
42
  'OB3Verifier',
38
43
  'OB3VerificationError',
44
+ 'add_data_integrity_proof',
45
+ 'verify_data_integrity_proof',
39
46
  'StatusRegistry',
40
47
  'build_did_document',
41
48
  'build_status_list_credential',
42
49
  'check_credential_status',
50
+ 'did_key_from_pem',
43
51
  'did_web_from_url',
44
52
  'encode_bitstring',
53
+ 'multikey_from_pem',
45
54
  'resolve_did',
55
+ 'resolve_verification_method',
46
56
  'sign_status_list_credential',
47
57
  'status_entry',
48
58
  ]