> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissioned Products & Compliance

> How Composer API handles product authorization for deposits into permissioned vaults, and which permissioned vaults are supported today.

Some vaults only accept a deposit after their issuer or protocol has authorized it, for example through an allowlist, a compliance check, or a signed permission. Composer API supports deposits into these permissioned vaults. While preparing the transaction, Composer checks the product's authorization requirements and, when needed, requests authorization data and includes it in the deposit call, so the product's access controls are enforced rather than bypassed.

<Note>
  Composer does not perform KYC or AML checks, onboard users, or grant access. Eligibility rules and onboarding remain with the issuer or protocol, and with you as the integrator.
</Note>

## Availability

* **Supported vaults are open to every integrator.** The vaults listed in [Supported permissioned vaults](#supported-permissioned-vaults) work through Composer API with no separate vault activation. The usual Composer API authentication requirements still apply; see [Quickstart](/composer/composer-api/quickstart).
* **Each new permissioned product is integrated by LI.FI first.** Authorization mechanisms differ between products, so LI.FI integrates each product's authorization service before deposits can route to it. To offer a permissioned vault that is not listed, [contact the LI.FI team](#add-a-permissioned-vault).

## Who handles what

| Party | Role in the deposit experience |
| - | - |
| Your application | Lets the user select a vault and funding asset, directs them to onboarding if the product requires it, requests the deposit from Composer API, and presents the transaction and its outcome. |
| Composer | Checks existing authorization where supported, obtains and includes authorization data when needed, and simulates the transaction before returning it for the user to sign. |
| Issuer or protocol | Defines the eligibility rules and the authorization mechanism, onboards users where required, and verifies the authorization onchain when the deposit executes. |

## How the deposit flow works

1. **Onboard the user, if required.** Direct the user to the issuer's onboarding process when the product requires it. Some products authorize based on wallet screening and need no separate onboarding step.
2. **Request the deposit.** Send the flow to `POST /compose` with the user's real address, the funding asset, and the destination vault. See [Build a Flow](/composer/composer-api/guides/build-a-flow) for the flow and input bindings. Do not use a placeholder address: Composer derives the user's execution proxy from it, and authorization is evaluated for that address.
3. **Composer checks eligibility and handles authorization.** Composer checks whether the deposit is allowed and obtains any authorization data required to prepare it. If the product refuses the deposit, Composer returns an error. Where the product supports existing permissions, Composer can use a valid permission without requesting a new signature. The address whose permission is checked depends on the product; it can be the user's execution proxy rather than the user's wallet. The form of the authorization, such as a signature or a permission grant, is set by the product.
4. **Composer prepares the transaction.** Composer includes any required authorization data in the deposit call, combines it with the funding steps such as swaps, and simulates the result. An HTTP 200 response means the authorization requirements were satisfied during preparation, not necessarily that a new authorization was issued. There is no separate eligibility field to read.
5. **Execute and show the outcome.** The user signs and submits the transaction, the execution proxy runs the calls, and the protocol verifies the authorization as part of the deposit. For products with delayed settlement, track share delivery separately from the funding transaction.

<Warning>
  Authorization data can be time-limited or single-use. Request a new transaction when the user is ready to sign instead of storing prepared calldata for later submission.
</Warning>

See [Execution Model](/composer/composer-api/concepts/execution-model) for how execution proxies and the compile pipeline work.

## Handling outcomes

Authorization runs while Composer prepares the transaction, so a refused or failed authorization is returned as a [`ComposeError`](/composer/composer-api/reference/error-codes) on `POST /compose` and no calldata is produced.

| Outcome | Error kind | HTTP | What your application should do |
| - | - | - | - |
| Authorization requirements satisfied and transaction prepared | None | 200 | Present the prepared transaction for the user to sign. |
| The product refused the deposit, for example because the address is not eligible | `resolution_rejected` | 422 | Do not retry the same request. Show the message and, where relevant, direct the user to the issuer's onboarding. |
| The authorization service could not be reached or returned an unusable response | `resolution_error` | 503 | Retry with backoff. |
| The prepared transaction reverted in simulation under the default `run.simulationPolicy: "strict"` | `simulation_revert` | 422 | Inspect the revert details before retrying. |
| The prepared transaction reverted with `run.simulationPolicy: "allow-revert"` | `simulation_revert` | 206 | The partial response includes calldata and revert diagnostics; do not treat it as a successful simulation or submit it without addressing the failure. |

In the raw HTTP error response, read `error.kind` and `error.message`. The latter is human-readable: surface or log it, but do not match its text programmatically. An HTTP 206 response also has `success: false` and carries partial result data. See [Allow-revert mode](/composer/composer-api/reference/error-codes#allow-revert-mode).

## How this relates to RWA routing

Three separate layers can affect a deposit into a tokenized real-world asset:

| Layer | Who decides | Where it applies |
| - | - | - |
| Issuer eligibility | The issuer or protocol, through its onboarding and onchain rules | Every deposit, whichever API you use |
| Composer authorization | The product's existing permission or authorization service, checked by Composer | Deposits prepared through Composer API (this page) |
| Partner RWA policy | Your company, in the LI.FI Partner Portal | LI.FI quote and route endpoints, for tokens tagged `rwa` |

This is why outcomes differ between APIs. When the LI.FI quote API declines a permissioned asset, it returns no route together with a reason. Composer API returns a `resolution_rejected` error instead. See [Real World Assets](/enterprise/real-world-assets) for eligibility checks and the partner RWA policy on the LI.FI API.

## Supported permissioned vaults

The following permissioned vaults are supported through Composer API. Coverage changes as products are added. Check [Supported Protocols & Chains](/composer/protocols-and-chains) for current routing coverage.

### Nest

Nest vault share tokens use the same address on every chain listed.

| Vault | Share token | Chains |
| - | - | - |
| Nest Alpha Vault (nALPHA) | `0x593ccca4c4bf58b7526a4c164ceef4003c6388db` | Ethereum, BNB Chain, World Chain, Plasma, Plume |
| Nest Treasury Vault (nTBILL) | `0xe72fe64840f4ef80e3ec73a1c749491b5c938cb9` | Ethereum, BNB Chain, World Chain, Plasma, Plume |
| Nest Basis Vault (nBASIS) | `0x11113ff3a60c2450f4b22515cb760417259ee94b` | Ethereum, BNB Chain, World Chain, Plasma, Plume |
| Nest BlackOpal LiquidStone II Vault (nOPAL) | `0x119dd7daff816f29d7ee47596ae5e4bdc4299165` | Ethereum, BNB Chain, World Chain, Plasma, Plume |
| Nest Credit Vault (nCREDIT) | `0xa5f78b2a0ab85429d2dfbf8b60abc70f4cec066c` | Ethereum, BNB Chain, Plasma, Plume |
| Nest ACRDX Vault (nACRDX) | `0x2a3e301dbd45c143dfbb7b1ce1c55bf0bbf161cb` | Ethereum, BNB Chain, Plasma, Plume |
| Nest Wisdom Vault (nWISDOM) | `0x29bf22381a5811dec89dc7b46a5ce57ad02c0240` | Ethereum, BNB Chain, Plasma, Plume |
| Nest Falcon Vault (nFALCON) | `0x066d10e240999aea6798b2e2ca0bdac2923cbdff` | Ethereum, BNB Chain, Plume |
| Nest OnRe Vault (nONRE) | `0x1939531162b2780e2fb5e01d68c6f545467a786d` | Ethereum, BNB Chain, Plume |
| Prime Vault (nPRIME) | `0x6fec234e8801ed88964bc058a0f9fbcc9fcbd2eb` | Ethereum, BNB Chain, Plume |
| Nest Liquid Credit Vault (nLCRD) | `0xdf45b8322ea4ce898331602e2d1f3d1a67ae0ee8` | Ethereum, Plume |
| Nest AXI Vault (nAXI) | `0x7488b23f4c26b44eef2e0766896be47443e86d79` | Ethereum, Plume |
| Nest BlackRock iShares AAA CLO Active ETF Vault (nCLOA) | `0x63810d7f1c7b4dbfb60c173ba120a2be98b59e13` | Ethereum, Plume |
| Plume Factor Vault (FACTOR) | `0x1f37620a0e0660db3cdbb8cdbf62d8099f959925` | Ethereum, Plume |

### Maple Syrup

Maple checks lender permission for the execution proxy, not the user's wallet. If that proxy is already authorized, Composer uses the existing permission without requesting a new signature. Otherwise, Composer obtains a signature and prepares an authorize-and-deposit call; a single transaction can deposit into only one Syrup pool while the proxy is not yet authorized. Permission is checked again when preparing a later transaction because it can be revoked.

| Pool | Pool token | Chains |
| - | - | - |
| syrupUSDC | `0x80ac24aa929eaf5013f6436cda2a7ba190f5cc0b` | Ethereum |
| syrupUSDT | `0x356b8d89c1e1239cbbb9de4815c39a1474d5ba7d` | Ethereum |
| syrupUSDG | `0x87b65c4aaffa76881f9e96f3e7ed945ddfc3cd7a` | Ethereum |

## Add a permissioned vault

<Card title="Contact the LI.FI team" icon="envelope" href="https://li.fi/contact-us/">
  Tell us which permissioned vault you want to offer or distribute, the chains you need it on, and how the issuer authorizes deposits. We scope the authorization integration with you and the issuer.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.