---
title: "Setup"
description: "Create a Wallet2 service (type wallet2) inside a tenant using the walt.id Enterprise Stack."
stack: "Enterprise Stack (commercial) — version 1.1.1"
stack_version: "1.1.1"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/wallet2-service/setup
generated: 2026-10-01
---
# Setup

**There are two ways to set up a new Wallet2 service:**

- [**Composable init (recommended)**](#creating-a-wallet2-with-composable-init): Bootstrap a Wallet2 instance and optional dependency services (KMS, DID Store, DID Service, Credential Store) in one call via `POST /v1/{target}/resource-api/services/init`.
- [**Manual setup**](#creating-a-wallet2-without-dependencies): Create a standalone Wallet2 with `"type": "wallet2"` via the resource API. Optionally provide a static key and DID, then [attach dependencies](#attach-service-dependencies-to-wallet2-after-creation) as needed.

**Note:**

Each Wallet2 instance corresponds to a single wallet identified by a unique **target** (e.g. `waltid.tenant1.wallet1`). The resource type must be `"wallet2"`. Use the `/v2/{target}/wallet-service-api/...` endpoints for all Wallet2 operations.

**Note:**

Need the legacy draft Wallet (`type: "wallet"`, `/v1` API)? See [Wallet Service setup](https://docs.walt.id/enterprise-stack/services/wallet-service/setup.md). That path requires the `wallet-draft-routes` feature.

## Prerequisites

- **A tenant** — An existing tenant in your organization.
- For full receive/present persistence: plan for [KMS](https://docs.walt.id/enterprise-stack/services/key-management-service/overview.md), [DID Service](https://docs.walt.id/enterprise-stack/services/did-service/overview.md), [DID Store](https://docs.walt.id/enterprise-stack/services/did-store-service/overview.md), and [Credential Store](https://docs.walt.id/enterprise-stack/services/credential-store-service/overview.md).
- Optional: [Client Attestation Service](https://docs.walt.id/enterprise-stack/services/client-attestation-service/overview.md), [Holder Policy Store](https://docs.walt.id/enterprise-stack/services/holder-policy-store-service/overview.md), [Trust Registry Service](https://docs.walt.id/enterprise-stack/services/trust-registry-service/overview.md) (signed Request Object anchors from relying-party identities).

---

## Creating a Wallet2 with Composable Init

Composable init creates a **Wallet2** (`type: wallet2`) and can create or link KMS, keys, DID store/service, DIDs, and credential store in dependency order. The endpoint is idempotent when `createIfNotFound` is `true`.

**Option: CURL**

Endpoint: `POST /v1/{target}/resource-api/services/init` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html#/Service%20%7C%20Resource/post_v1__target__resource_api_services_init)

**Example Request** (full wallet bootstrap)

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{org}.{tenant}/resource-api/services/init' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "wallet": {
    "createIfNotFound": true,
    "target": "waltid.tenant1.wallet1",
    "kms": {
      "createIfNotFound": true,
      "target": "waltid.tenant1.wallet1.kms",
      "key": {
        "createIfNotFound": true,
        "target": "waltid.tenant1.wallet1.kms.wallet_key",
        "config": {
          "backend": "jwk",
          "keyType": "Ed25519"
        }
      }
    },
    "didStore": {
      "createIfNotFound": true,
      "target": "waltid.tenant1.wallet1.didstore"
    },
    "didService": {
      "createIfNotFound": true,
      "target": "waltid.tenant1.wallet1.didservice",
      "dependencies": [
        "waltid.tenant1.wallet1.kms",
        "waltid.tenant1.wallet1.didstore"
      ],
      "did": {
        "createIfNotFound": true,
        "target": "waltid.tenant1.wallet1.didstore.wallet_did",
        "type": "key"
      }
    },
    "credentialStore": {
      "createIfNotFound": true,
      "target": "waltid.tenant1.wallet1.credentialstore"
    }
  }
}'
```

**Path Parameters**

- `orgID` — Organization base URL / host alias (e.g. `test.enterprise-sandbox.waltid.dev` on sandbox).
- `target` — Tenant path where initialization runs (`{organizationID}.{tenantID}`), e.g. `waltid.tenant1`.

**Body Parameters (wallet block)**

- `wallet.createIfNotFound` — Create the Wallet2 if missing.
- `wallet.target` — Full Wallet2 resource path, e.g. `waltid.tenant1.wallet1`.
- `wallet.config` (optional) — Wallet configuration object:
  - `staticDid` / `staticKey` — Static holder identity when you do not attach KMS / DID store.
  - `requestObjectX509Trust` (optional) — PEM trust anchors for authenticating `x509_san_dns` / `x509_hash` Request Objects. Unioned with relying-party certificates from a linked [Trust Registry](https://docs.walt.id/enterprise-stack/services/trust-registry-service/wallet2-integration.md). When the union is empty, those client ID prefixes fail closed.
    - `x509TrustAnchorsPem` — Non-empty list of unique PEM certificates. The verifier leaf in `x5c` must chain to one of these anchors. If KeyUsage is present it must include `digitalSignature`; if absent, RFC 5280 treats the key as unrestricted. If ExtendedKeyUsage is present it must include TLS `clientAuth` (`1.3.6.1.5.5.7.3.2`) or mdoc reader authentication (`1.0.18013.5.1.6`); if absent, EKU is unrestricted. Include both extensions when issuing verifier Request Object leaves.
  - `preRegisteredClients` (optional) — Map of OpenID4VP `pre-registered` client IDs to stored client metadata. Empty (the default) fails those identifiers closed. Unsigned pre-registered requests also need `redirect_uris` on each entry; registration plus in-band `client_metadata` is `invalid_client`. URL-shaped ids match only when the raw string is a map key.
  - `requestObjectAudience` (optional) — Expected `aud` claim in signed Request Objects. Defaults to `https://self-issued.me/v2`. Must be non-blank and must not have surrounding whitespace.
- `wallet.kms` / `didStore` / `didService` / `credentialStore` (optional) — Nested composable blocks with their own `target`, `createIfNotFound`, and configs.

You can also include an `issuer` block in the same request to bootstrap Issuer2 alongside Wallet2.

**Response Codes**

- `200` / `201` — Initialization completed (created and/or reused existing resources).

---

## Creating a Wallet2 without Dependencies

Create a Wallet2 service with `"type": "wallet2"`. Optionally provide a static key and DID when you do not attach KMS / DID store.

**Option: CURL**

Endpoint: `POST /v1/{target}/resource-api/services/create` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html#/Service%20%7C%20Resource/post_v1__target__resource_api_services_create)

**Example Request**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v1/{target}/resource-api/services/create' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "type": "wallet2",
  "configuration": {
    "staticKey": {
      "type": "jwk",
      "jwk": {
        "kty": "OKP",
        "d": "wZ69WYFIZHYEC9gWsRYCIHsJ4G5qdZeCrCry6szGij4",
        "crv": "Ed25519",
        "kid": "I-bh2IYP93feK_dIYA7QaNSHoRlftw53KYpNYPdEpNQ",
        "x": "sD8DqvgzEjQaex5p4NNp_Qyd8knJAJfZY7Ge8vCmBGY"
      }
    },
    "staticDid": "did:key:z6MkrKFXimvdRgYnsFeyQq5sUn4vmXJVDHriHJKpgy6oaC6H"
  }
}'
```

**Body Parameters**

- `type` — Must be `wallet2`.
- `configuration` (optional):
  - `staticKey` — Key object associated with the wallet when no KMS is linked.
  - `staticDid` — DID string associated with the wallet when no DID store is linked.
  - `requestObjectX509Trust` (optional) — Pin PEM trust anchors used to authenticate X.509 Request Objects (`x509_san_dns` / `x509_hash`). Unioned with relying-party certificates from a linked [Trust Registry](https://docs.walt.id/enterprise-stack/services/trust-registry-service/wallet2-integration.md). When the union is empty, those prefixes fail closed.
    - `x509TrustAnchorsPem` — Non-empty list of unique PEM certificates. The verifier leaf must chain to one of these anchors. If KeyUsage is present it must include `digitalSignature`; if absent, RFC 5280 treats the key as unrestricted. If ExtendedKeyUsage is present it must include TLS `clientAuth` (`1.3.6.1.5.5.7.3.2`) or mdoc reader authentication (`1.0.18013.5.1.6`); if absent, EKU is unrestricted. Include both extensions when issuing verifier Request Object leaves.
  - `preRegisteredClients` (optional) — Map of OpenID4VP `pre-registered` client IDs to stored client metadata. Empty fails those identifiers closed. Unsigned entries need `redirect_uris`; do not send request `client_metadata` for a registered id (`invalid_client`).
  - `requestObjectAudience` (optional) — Expected `aud` claim in signed Request Objects. Defaults to `https://self-issued.me/v2`.

**Path Parameters**

- `target` — `{organizationID}.{tenantID}.{walletID}`, e.g. `waltid.tenant1.wallet1`.

**Response Codes**

- `201` — Wallet2 created successfully.

---

## Attach Service Dependencies to Wallet2 After Creation

Attach KMS, DID store, credential store, client-attester, policy-store, or trust-registry after creation:

**Option: CURL**

Endpoint: `POST /v2/{target}/wallet-service-api/dependencies/add` | [API Reference](https://enterprise.sandbox.walt.id/swagger/index.html#/Service%20%7C%20Wallet2%20Service/post_v2__target__wallet_service_api_dependencies_add)

**Example Request**

```bash
curl -X 'POST' \
  'https://{orgID}.enterprise-sandbox.waltid.dev/v2/{target}/wallet-service-api/dependencies/add' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer {yourToken}' \
  -H 'Content-Type: application/json' \
  -d '{
  "dependency": "waltid.tenant1.credential-store-1"
}'
```

**Path Parameters**

- `target` — `{organizationID}.{tenantID}.{walletServiceID}`, e.g. `waltid.tenant1.wallet1`.

**Body Parameters**

- `dependency` — Resource ID of the dependency to link.

**Response Codes**

- `201` — Dependency attached.

## Next Steps

- [Receive credentials](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-receiving/overview.md) — claim a credential offer into the wallet.
- [Present credentials](https://docs.walt.id/enterprise-stack/services/wallet2-service/credential-presenting/overview.md) — present stored credentials to a verifier.
- [Default Requests](https://docs.walt.id/enterprise-stack/services/wallet2-service/default-requests.md) — optional: pin the holder key and DID the wallet uses, so presenting only needs the request URL.
