> For the complete documentation index, see [llms.txt](https://docs.toolkit.equs.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.toolkit.equs.ai/docs/crypto/decrypt-payload-embed-ui.md).

# Decrypt Payload (Embed UI)

Have the User's Web Wallet decrypt data you encrypted to their key, with their approval, and get the result back encrypted to you

You can keep data encrypted to a User's wallet key and still use it when you need to. `decryptPayload` hands the ciphertext to the User's Web Wallet, the User approves, and the wallet decrypts it with a key that never leaves the wallet. What comes back is re-encrypted to a key only you hold, so the plaintext is never exposed on the way.

{% hint style="info" %}
This uses the **Web Wallet**, which is off by default and available on request.
{% endhint %}

**Before you start** you need Embed UI initialized - see [Embedded UI](/docs/embedded-ui/overview.md) - and the User signed in to the Web Wallet - see [Embedding Web Wallet](/docs/embedded-ui/embedding-web-wallet.md).

### How it works

1. **Ahead of time**, encrypt the data - or a symmetric key that protects it - to the User's key-agreement public key from their DID document, as a compact JWE. Store it with the data it protects.
2. **When you need it**, generate an ephemeral P-256 key pair and call `decryptPayload` with the JWE and the public half.
3. **The User approves.** The Web Wallet opens over your page and shows the preview you supplied.
4. **You get the result** in `onSuccess`: the plaintext, re-encrypted as a JWE to your ephemeral public key. Decrypt it with the private half.

### Start the decryption

```javascript
import { decryptPayload } from '@equs-ai/dtk-embedded-ui'

decryptPayload({
  payload,     // compact JWE encrypted to the User's key-agreement key
  senderEpk,   // your ephemeral public key: { kty: 'EC', crv: 'P-256', x, y, kid? }
  preview: {
    text: 'Unlock the card you saved with us',
    tenantData: { name: 'Demo Shop', logo: logoUrl },
  },
  onLoading,
  onSuccess: ({ result }) => { /* a JWE encrypted to senderEpk */ },
  onError: (error) => { /* show the failure */ },
})
```

| Option      | Required | Description                                                                                                                                                                         |
| ----------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payload`   | Yes      | The compact JWE to decrypt, encrypted to the User's key-agreement key                                                                                                               |
| `senderEpk` | Yes      | Your ephemeral public key as a P-256 JWK, `{ kty: 'EC', crv: 'P-256', x, y, kid? }`. The result is encrypted to it, and `kid`, if you set one, is echoed in the result's JWE header |
| `preview`   | No       | What the User sees before approving: `{ text?, image?, tenantData? }`, where `tenantData` is `{ name?, logo?, description? }`                                                       |
| `onLoading` | No       | `(loading: boolean) => void`. The wallet takes a moment to open, so use this to show a spinner                                                                                      |
| `onSuccess` | No       | `({ result }) => void`. `result` is the plaintext as a JWE encrypted to `senderEpk`                                                                                                 |
| `onError`   | No       | `(error: unknown) => void`. Called when the wallet can't decrypt the payload                                                                                                        |

To close the wallet mid-flow, call `cleanUpDecryptPayload()`. `cleanUpEmbeddedUi` calls it for you.

### Without the User present

The same decryption is available server to server, on the User's behalf - see [Decrypt Payload (API)](/docs/crypto/decrypt-payload-api.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.toolkit.equs.ai/docs/crypto/decrypt-payload-embed-ui.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
