Skip to main content

Enforcing an Ecosystem as a Wallet

This page explains how ecosystem constraints — such as those required by EUDI — are enforced by the wallet.

For an overview of how ecosystems operate, see Ecosystem Enforcement Overview.

Prerequisites

A wallet must have ecosystems available before it can enforce them on interactions. See Determining available ecosystems below for how a wallet instance determines this.

Determining available ecosystems

A wallet instance checks two sources, in order:

  1. Registration — if the wallet instance is registered with a Wallet Provider, the ecosystems selected by that Provider apply. See Enforcing an Ecosystem as a Provider.

  2. Own configuration — if the wallet instance is not registered with a Provider, it falls back to its own organization's configuration. See Enabling Ecosystems for instructions on selecting ecosystems for a standalone wallet organization.

How enforcement works

Ecosystem constraints can be checked at up to two points in a flow.

First gateway: handle-invitation

Every credential offer or proof request starts with:

POST /api/interaction/v1/handle-invitation

{
"ecosystem": "EUDI",
{{...}}
}

You can name an ecosystem explicitly, as shown, or omit it. If no ecosystem is named and enforcement is required (see Requiring ecosystem enforcement below), the system falls back to auto-detection, iterating through every ecosystem available to the wallet until one returns a TRUSTED result, or none do.

The response includes ecosystemErrors, giving the result of every ecosystem checked — just the one named, or all of them if auto-detection ran. See Trust verdicts in the Reference doc for the full shape.

  • If enforcement is required, the call only succeeds when at least one ecosystem returns TRUSTED; otherwise it fails, and the error response carries the same ecosystemErrors detail so you can see why.
  • If enforcement is not required, the call can succeed regardless of result — including if nothing came back TRUSTED at all.

Second gateway: issuance-accept or submit-presentation

Depending on ecosystem, other trust checks may occur in the next call of the interaction:

  • Issuance: POST /api/interaction/v1/issuance-accept
  • Presentation: POST /api/interaction/v1/submit-presentation

Both follow the same success/failure/ecosystemErrors shape as the first gateway. A credential offer, for example, can pass handle-invitation and still fail issuance-accept if it does not hold up under these further checks.

Requiring ecosystem enforcement

Any ecosystem available to a wallet organization is available for use, either passed in handle-invitation or found through auto-detection. To require that every interaction pass at least one ecosystem's constraints, update the wallet organization:

PATCH /api/organisations/v1/{id}

{
"configuration": {
"enforceEcosystemAsHolder": true
}
}

Looking up interaction partner details

Once issuance-accept or submit-presentation succeeds, the credential or proof request exists in the wallet, and its detail response includes a trustInformation object summarizing how it was resolved:

GET /api/credential/v1/{id} GET /api/proof-request/v1/{id}

"trustInformation": {
"result": "TRUSTED",
"name": "EUDI",
"receivedAt": "2026-09-11T12:25:06.715Z",
"ecosystemErrors": {
"EUDI": {
"result": "TRUSTED",
"error": {
"code": "BR_0486",
"message": "..."
}
}
}
}
  • result is TRUSTED or UNTRUSTED. If ecosystem enforcement is required, either because it was passed with handle-invitation or because it is required by the configuration, the top-level result must be TRUSTED.
  • ecosystemErrors repeats the same per-provider detail from the two gateways, for whichever ecosystems were actually checked. A TRUSTED overall result can still show a rejected entry here if a different provider failed. Note the naming: entries here use NOT_TRUSTED, while trustInformation.result itself uses UNTRUSTED.
  • Resolution is also recorded as an ECOSYSTEMS_RESOLVED history event, using the same per-provider shape.

For the full resolved detail about the interaction partner — not just the verdict — call:

  • GET /api/credential/v1/{id}/trust-detail
  • GET /api/proof-request/v1/{id}/trust-detail