Changelog

See the most recent changes in Paradym.

Wallet Attestation Bug Fixes

August 5, 2026

Bug fix

Two bugs regarding Trusted Wallets have been fixed:

  • Wallet attestations signed by DIDs are now correctly matched against the DIDs in the Trusted Wallet.
  • When no Trusted Wallet is configured, X.509 certificate-signed attestations are now correctly trusted.

Older mdoc credentials with a string key id verify again

July 28, 2026

Bug fix

mdoc credentials issued with an older version of Paradym encoded the COSE kid (key id) header as a text string (tstr) instead of a byte string (bstr). After the stricter header validation that shipped alongside x509 revocation checking, presenting one of these credentials failed verification with Error decoding UnprotectedHeaders: Expected Uint8Array, received string at "4", and the verifier returned invalid_request ("One or more presentations failed verification").

Paradym now accepts a legacy string kid and normalises it to its bytes during decoding, so these previously issued mdoc credentials verify again. No action or re-issuance is required, and the change does not affect signature verification (the kid lives in the unprotected headers, which are not part of the signed data). Newly issued credentials are unaffected.


Projects are now called wallets

July 23, 2026

EnhancementDeprecationBreaking change

Projects in Paradym are now called wallets, across the API, the API Reference, the documentation and the dashboard. Nothing breaks: everything that used the project naming keeps working, and the sections below describe what changed and what is now deprecated.

New canonical /v1/wallets API endpoints

Every API endpoint under /v1/projects/** is now also available under /v1/wallets/**, the new canonical path family. For example, GET /v1/projects/{projectId}/webhooks becomes GET /v1/wallets/{walletId}/webhooks.

The two families behave identically (same authentication and behaviour), but they use their own vocabulary and do not mix. Responses served under /v1/wallets/** use wallet naming: the path parameter is walletId, body fields such as projectId become walletId, the member's project object becomes wallet, and pagination links point back to /v1/wallets. Responses served under /v1/projects/** are unchanged and keep the project naming. Pick one family per integration; a wallet request never returns project fields, and a project request never returns wallet fields.

The /v1/projects/** family is now deprecated. It keeps working for existing integrations, but it will not receive new features and will eventually be removed, so new integrations should use /v1/wallets/** and existing integrations should migrate. The deprecated endpoints are marked as such in the API Reference, each one pointing to its /v1/wallets/** replacement, and their responses carry a Deprecation: true header.

Webhook payloads now contain a walletId field alongside the existing projectId field (regardless of which path family you manage subscriptions with). projectId is deprecated there and will be removed in a future version, so switch to walletId going forward.

API Reference, documentation and OpenAPI document

The API Reference and the documentation now present the wallet endpoints as the canonical way to use the Paradym API. The endpoint groups previously shown as "Projects" and "Project Profile" are now "Wallets" and "Wallet Profile", and all documented example requests use the /v1/wallets/{walletId} paths.

The canonical OpenAPI document also uses wallet naming for its schema and operation names: request and response types such as CreateProject and ProjectProfile are now CreateWallet and WalletProfile, and operation ids such as ProjectsCreateProject are now WalletsCreateWallet. The HTTP API itself is unchanged. If you generate a client from the OpenAPI document, regenerating it will rename the affected types and methods, so update your code accordingly. The document for the deprecated /v1/projects/** family keeps the previous names. A future major release of @paradym/sdk will adopt the new naming; the current release keeps working unchanged.

Dashboard

The dashboard now uses the name wallet everywhere: the wallet switcher in the top-left corner, the wallet settings (including the Wallet ID you use with the API), member invitations, and emails sent by Paradym such as invitation and certificate renewal notifications. To avoid confusion with the new naming, the Custom Wallet settings tab is now called Invitation Page.

Only the naming changes: your wallets, their IDs, members, and settings are untouched, and no action is required. A few dashboard URLs moved along with the rename: the wallet settings page from /settings/project to /settings/wallet, the wallet selector from /app/select-project to /app/select-wallet, and the invitation accept page from /verify/project/invitation to /verify/wallet/invitation. Old links (including invitation emails that were already sent) redirect automatically. See the documentation for how wallets and members work.


Standalone attestation proof type during issuance

July 14, 2026

Enhancement

Require Key Attestations during issuance

July 9, 2026

New featureBuilder Tier

Building on Trusted Wallets, you can now require a key attestation when issuing a credential. A key attestation lets the wallet provider vouch for how the credential's key is protected, so you can limit issuance to keys that meet certain security requirements — as long as you trust the wallet provider.

Add a keyAttestations object to an SD-JWT VC or mDoc credential template (or use the new Key Attestation section in the credential template editor). Its presence means a key attestation is required, and you can optionally constrain two ISO 18045 levels:

{
  "trustedWallets": ["<trusted-entity-id>"],
  "keyAttestations": {
    "keyStorage": ["iso_18045_high"],
    "userAuthentication": ["iso_18045_moderate"]
  }
}
  • keyStorage — the required attack potential resistance of the key storage.
  • userAuthentication — the required resistance of the user authentication protecting the key.

Both lists are optional (you can require an attestation without constraining the levels), and levels are compared hierarchically so a stronger attested level satisfies a weaker requirement. Because the attestation signer is verified against your trusted wallets, keyAttestations requires at least one trustedWallets entry on the template.

This is non-breaking: templates without keyAttestations are unaffected and do not require a key attestation. See the Key attestations documentation for details.


Support for Trusted Wallets

July 9, 2026

New featurePro Tier

You can now limit which wallets are allowed to receive a credential during issuance, using OpenID4VCI wallet attestations. This mirrors how trusted issuers already limit who can issue a credential during verification, and reuses the same Trusted Entities.

Trusted entity types

Every DID, X.509 certificate and ETSI LoTE on a trusted entity now has a type: issuer (the default, existing behaviour) or wallet. Issuer entries are used to trust the issuer of a credential during verification; wallet entries are used to trust the wallet during issuance. In the dashboard you can pick the type when adding a DID or certificate to a trusted entity.

Paradym also now supports the EU Wallet Providers List LoTE profile. Its type is inferred automatically as wallet, and credential types do not apply to it. Existing issuer LoTEs and trusted entities are unaffected — everything defaults to issuer.

Trusted wallets on credential templates

SD-JWT VC and mDoc credential templates now accept a trustedWallets field: a list of trusted entity ids whose wallet-typed entries are allowed to receive the credential. Set them via the API when creating or updating a template, or from the new Trusted Wallets section in the credential template editor. When reading a template, request ?include=trustedWallets to get the linked entities back in the response.

When trusted wallets are configured, a wallet attestation is required during issuance and must be signed by one of the trusted wallet providers, otherwise issuance is rejected. When none are configured, any wallet can receive the credential, so this is a non-breaking change. If a credential offer bundles multiple credentials, their trusted wallets are intersected — a wallet is accepted only if its provider is trusted by every credential in the offer that restricts wallets.

When a trusted-wallet credential also uses an Authorization Server, the wallet is trusted through its attestation, so issuance is gated by that attestation and the Authorization Server's redirect URI allow-list is not enforced.

See the Trusted Entities documentation for details.


Support for did:webvh

July 8, 2026

New feature

You can now use the did:webvh DID method when signing credential and presentation templates, alongside the existing did:web and did:cheqd methods.

Select did:webvh when configuring the signing DID for a credential or presentation template. If the DID does not exist yet, Paradym creates and hosts it for you, just like did:web. See How it works for more information.


Direct wallet deeplinks for offers, requests and invitations

July 7, 2026

New feature

Credential offers, presentation requests and DIDComm invitations now include direct deeplink URIs in their API responses, alongside the existing universal-link based offerUri / authorizationRequestUri / invitationUri.

Until now these URIs pointed to a Paradym (or custom wallet) invitation page, which then deeplinks into the wallet. In some flows you might want to directly link into the wallet outside of the Paradym invitation page.

The new fields give you the raw scheme directly:

  • OpenID4VC issuance offer: offerDeeplinkUri (openid-credential-offer://…) and offerDeeplinkQrUri
  • OpenID4VC presentation request: authorizationRequestDeeplinkUri (openid4vp://…) and authorizationRequestDeeplinkQrUri
  • DIDComm invitation: invitationDeeplinkUri (didcomm://…) and invitationDeeplinkQrUri

The …DeeplinkUri fields are plain deeplink strings you can place behind a button or render into your own QR code. The …DeeplinkQrUri fields return a QR code image (like the existing …QrUri) whose contents are the deeplink instead of the universal link.

These fields are additive and non-breaking, existing integrations keep working unchanged. See Issue credentials and Verify credentials, or the API Reference for more information.


EU Trust lists now available in the Builder tier

July 6, 2026

Enhancement

EU Lists of Trusted Entities (LoTEs) are now available starting from the Builder tier, instead of requiring the Pro tier.

You can now point a trusted entity at a LoTE URL and let Paradym fetch, validate, and keep the list of trusted issuance and revocation certificates up to date automatically, on any Builder plan or higher. Configure it under Trusted Entities or via the API.

No action is required. Existing projects on the Builder tier immediately gain access to this feature.


Interoperability with German EUDI Wallet

July 3, 2026

Enhancement

Paradym can now verify the PID and EEAs from the German EUDI Wallet, as well as issue EAAS.

  • ETSI LoTEs of the EU PID Providers List type now cover any SD-JWT VC credential type within the urn:eudi:pid: namespace, so the LoTE is used automatically when verifying a country-specific PID type such as Germany's urn:eudi:pid:de:1. The German test trust list can now also be imported.
  • As a temporary workaround for the German EUDI Wallet rejecting DCQL queries that contain trusted_authorities, Paradym omits trusted_authorities from the query when an OpenID4VP request is signed with an Access Certificate issued by the German Sandbox registrar. This may change at any point in the future. The configured trusted issuers are still fully validated by Paradym when the presentation is received.
  • You can now copy the public key of a certificate signing request from the dashboard. This makes the registration in the German EUDI Wallet Sandbox Registrar easier. Under My Certificates in the "Trust" tab, open the menu of a request and choose Copy public key to copy its SPKI PEM (-----BEGIN PUBLIC KEY-----). The existing Copy request option still copies the full PKCS#10 request.

To verify the German PID, configure a trusted entity with the German test trust list and request urn:eudi:pid:de:1 in your presentation template.