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

# Widget de prova de titularitat de cartera (Travel Rule)

> Widget allotjat de Didit que prova el control d'una cartera amb signatura de missatges, test de Satoshi, captura o autodeclaració (Travel Rule).

El widget de verificació de titularitat de cartera és una pàgina allotjada que demostra que un dels teus clients controla una adreça de cartera de criptomonedes concreta. Segons el TFR de la UE, un VASP ha de verificar la titularitat d'una cartera autoallotjada (no allotjada) abans d'alliberar fons cap a aquesta cartera o des d'aquesta cartera per sobre del llindar sunrise. El widget és la manera com Didit recull aquesta prova sense que hagis de construir tu mateix els fluxos de signatura.

Una prova verificada marca l'[entrada de la llibreta d'adreces de carteres](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md#llibreta-d’adreces-de-carteres) corresponent com a `is_ownership_verified: true`, cosa que permet que una [transferència de Travel Rule](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md) vinculada avanci i surti de `UNCONFIRMED_OWNERSHIP`.

## Quan Didit la crea per a tu

Gairebé mai no cal crear tu mateix una sessió. Quan `auto_wallet_verification` està activat a la teva [configuració de Travel Rule](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md#configuració) (per defecte), Didit crea automàticament una sessió de widget en el moment de crear la transacció sempre que una transferència necessiti la prova, per part de l'usuari final, del control de la cartera:

* La transferència es troba en `UNCONFIRMED_OWNERSHIP`: la cartera de la contrapart s'ha declarat [autoallotjada](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md#carteres-autoallotjades-declarades) en el moment d'enviar la transferència.
* La transferència és de sortida i es troba en `COUNTERPARTY_VASP_NOT_FOUND`: no s'ha pogut identificar cap VASP de la contrapart, de manera que la prova de titularitat és el camí que queda per completar-la.

La sessió creada automàticament es retorna al bloc `action_required` de la transacció (`type: "wallet_ownership"`, amb la `url` que cal obrir), i els SDK la inicien automàticament en [l'enviament des del costat del client](https://docs.didit.me/ca/transaction-monitoring/sdk-transaction-submission.md#accions-requerides-de-l’usuari).
Les transferències entrants que Didit crea per a tu (un registre sunrise, una consulta `TRP` entrant o el tram entrant de la via `INTERNAL`) mai no reben una sessió creada automàticament, encara que acabin a `UNCONFIRMED_OWNERSHIP`.
Crea-la manualment amb `POST /v3/travel-rule/widget-session/` quan vulguis verificar una cartera abans que existeixi cap transferència, quan tinguis `auto_wallet_verification` desactivat, o per a una d'aquestes transferències entrants.

## Què demostra

El widget ofereix fins a quatre mètodes de prova. Els que apareixen depenen de com has creat la sessió i de la teva [configuració de Travel Rule](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md#configuració):

| Mètode | Com funciona | Quan s'ofereix |
| - | - | - |
| `MESSAGE_SIGNING` | El client signa amb la seva cartera una cadena de repte emesa per Didit. Admet carteres EVM, Solana, Bitcoin i Tron (per a Bitcoin, adreces legacy, SegWit anidat, SegWit natiu i Taproot); Didit verifica la signatura amb l'adreça, i si es signa amb un compte diferent del que es verifica, es rebutja amb un missatge clar per canviar de compte. Els comptes de contracte intel·ligent EVM (carteres intel·ligents ERC-4337) també signen: Didit consulta al propi contracte del compte, a la xarxa on està declarada la cartera, si la signatura és vàlida (ERC-1271), i per a un compte que encara no està desplegat comprova la signatura ERC-6492 que retorna la cartera, sense desplegar el compte ni enviar cap transacció. Els comptes de contracte intel·ligent es comproven a totes les xarxes EVM compatibles. Consulta [contracte de verificació de la signatura de missatges](#contracte-de-verificació-de-la-signatura-de-missatges) més avall. Les carteres instal·lades al navegador del client es descobreixen mitjançant els protocols EIP-6963 i Wallet Standard, de manera que cada extensió apareix com a opció de signatura pròpia. Actualment no està disponible vincular una aplicació de cartera mòbil independent, per exemple mitjançant un codi QR. | Sempre, per a les famílies de xarxes compatibles. |
| `SATOSHI_TEST` | El client envia des de la cartera una quantitat petita on-chain a una adreça de dipòsit que tu controles. El monitor de Didit comprova el remitent (en un compte de contracte intel·ligent EVM, el mateix compte, també quan un bundler ERC-4337 envia la transacció), la quantitat i que el dipòsit està confirmat on-chain, i després completa automàticament la prova quan es confirma; consulta [contracte de verificació de la prova Satoshi](#contracte-de-verificació-de-la-prova-satoshi) més avall. | Només quan passes un `satoshi_deposit_address` en crear la sessió i la xarxa és una xarxa EVM, Bitcoin o Solana, per tant mai en una sessió creada automàticament. |
| `SCREENSHOT` | El client puja una captura de pantalla de la cartera que mostra l'adreça (JPEG/PNG/WebP, fins a 10 MB). A diferència dels altres mètodes, mai es verifica automàticament: el teu equip de compliment la revisa des de la cua de revisió de captures de pantalla ([`GET /v3/travel-rule/wallet-proofs/`](https://docs.didit.me/ca/management-api/travel-rule/list-wallet-proofs)) i l'aprova o la rebutja ([`POST .../decision/`](https://docs.didit.me/ca/management-api/travel-rule/decide-wallet-proof)), o confirma la transferència des de la pestanya **Travel Rule** de la transacció a la consola o mitjançant [`POST .../travel-rule/ownership/`](https://docs.didit.me/ca/management-api/travel-rule/confirm-ownership) (per a una transferència en `UNCONFIRMED_OWNERSHIP` o una transferència entrant retinguda). | Només quan `allow_screenshot_proof` és `true` a la teva configuració. |
| `SELF_DECLARATION` | El client atesta la titularitat sense cap prova criptogràfica: és un últim recurs quan la jurisdicció ho tolera. | Només quan `allow_self_declaration` és `true` i la teva [`ownership_validation_mode`](https://docs.didit.me/ca/transaction-monitoring/travel-rule#modes-de-validació-de-la-titularitat) accepta una declaració per a la transferència vinculada: mai en `FULL`, i en `SIMPLIFIED` només per sota de `simplified_validation_threshold`. Iniciar-ne una que el mode no accepta respon amb `403`. |

### Contracte de verificació de la signatura de missatges

Enviar la signatura retorna `200` amb `status: "VERIFIED"` quan demostra el control de la cartera.
Retorna `400` i deixa la prova oberta, perquè el client pugui tornar a signar, amb un d'aquests valors de `code`:

| `code` | Significat |
| - | - |
| `SIGNATURE_INVALID` | La signatura no demostra la cartera: ha signat un altre compte o clau, o el missatge és diferent. En un compte de contracte intel·ligent, el seu contracte ha respost que la signatura no és pròpia. |
| `SIGNATURE_UNSUPPORTED_SCHEME` | La cartera ha signat en un format que Didit no verifica, per exemple un multisig de Bitcoin o una signatura completa BIP-322. |
| `SIGNATURE_LOOKUP_FAILED` | La cartera podria ser un compte de contracte intel·ligent, i la seva xarxa no s'ha pogut comprovar en aquest moment. La prova mai es verifica amb aquesta resposta; tornar a signar la torna a comprovar. |

### Contracte de verificació de la prova Satoshi

La verificació d'un dipòsit de prova Satoshi és asíncrona, perquè la transacció s'ha de veure on-chain i després confirmar-se.
Enviar el `txid` del dipòsit retorna `200` amb `status: "PENDING"` mentre el dipòsit no estigui confirmat on-chain: el `txid` es conserva, no es descarta.
Retorna `200` amb `status: "VERIFIED"` quan el dipòsit es confirma.
Retorna `400` amb `status: "REJECTED"` per a un dipòsit realment incorrecte: enviat des d'una altra cartera, amb una quantitat diferent de l’esperada a l'adreça de dipòsit, anterior al repte, o una transacció que ja ha servit per demostrar una altra cartera. La prova es tanca i el client pot iniciar-ne una de nova mentre la sessió tingui intents disponibles.
Un dipòsit que encara no està indexat també retorna `200` amb `status: "PENDING"`, i una consulta que falla per part de Didit retorna `400` amb el codi `DEPOSIT_LOOKUP_FAILED`: en tots dos casos la prova queda oberta i Didit continua comprovant.
Retorna `410` si la finestra de prova expira abans de veure un dipòsit vàlid.

Un cop s'ha enviat un `txid`, un procés en segon pla torna a comprovar el dipòsit pendent cada cinc minuts i completa la prova després que la transacció es confirmi, de manera que el client no necessita tornar a enviar el `txid`.
Quan passes un `satoshi_deposit_address`, el `expires_at` de la pròpia sessió del widget s'amplia fins a almenys la finestra de prova Satoshi de 24 hores, perquè el dipòsit tingui temps de confirmar-se abans que expiri la sessió.

## Flux

**1. Crear una sessió del widget**

Crida `POST /v3/travel-rule/widget-session/` amb la cartera que necessites verificar. Opcionalment, vincula-la a una transferència perquè la transferència avanci automàticament quan es demostri la titularitat.

**2. Obrir la URL retornada**

Envia el teu client a la `url` de la resposta. Allà completa una prova: no cal cap compte de Didit ni clau d'API; el token de la URL és l'autenticació.

**3. Detectar la finalització**

Quan una prova es verifica, el widget marca l'entrada de la llibreta d'adreces com a verificada i, si la sessió està vinculada a una transferència, la fa avançar. Vigila `travel_rule.status.updated` (transferències vinculades) o consulta periòdicament el context del widget.

### Crear una sessió del widget

Aquest exemple vincula la sessió a la [transferència autoallotjada declarada](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md#carteres-autoallotjades-declarades) de la guia de Travel Rule, de manera que `wallet_address` és la cartera de destinació d'aquesta transferència.
Una sessió vinculada a una transferència només accepta proves per a la cartera de la contrapart de la transferència.

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/widget-session/ \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "wallet_address": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9",
    "chain": "ETH",
    "holder_name": "Jane Doe",
    "vendor_data": "user-042",
    "transaction_id": "99999999-aaaa-bbbb-cccc-dddddddddddd",
    "satoshi_deposit_address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
    "callback_url": "https://yourapp.example/wallet-verified",
    "expires_in_minutes": 60
  }'
```

| Camp | Tipus | Descripció |
| - | - | - |
| `wallet_address` | cadena | L'adreça que cal verificar. |
| `chain` | cadena | Identificador de la xarxa per a l'adreça (per exemple `ETH`, `BTC`, `SOL`). Utilitza el mateix token que porten les teves transferències (`ETH`, no `ethereum`): el widget desa l'entrada de la llibreta d'adreces amb aquest `chain`, i una transferència en una altra xarxa no hi coincidirà. La signatura de missatges necessita una xarxa que Didit reconegui. |
| `holder_name` | cadena | Nom del titular de la cartera, utilitzat per a la coincidència del nom del beneficiari. |
| `vendor_data` | cadena | El teu identificador intern del titular, que es transfereix a l'entrada de la llibreta d'adreces creada. |
| `transaction_id` | cadena (uuid) | Opcional. UUID de transacció de Didit d'una transferència de Travel Rule que cal fer avançar quan la prova es verifiqui; un UUID desconegut retorna `404`, i una prova per a qualsevol cartera que no sigui la cartera de la contrapart de la transferència es rebutja amb `400`. Omet-lo per verificar una cartera de manera independent. |
| `satoshi_deposit_address` | cadena | Opcional. Una adreça de dipòsit que controlis; si la proporciones, habilita el mètode `SATOSHI_TEST`. |
| `callback_url` | cadena | Opcional. On el widget retorna el client després de completar el procés. |
| `expires_in_minutes` | enter | Opcional. Durada de l'enllaç creat, en minuts, de `5` a `10080` (per defecte `60`); s'augmenta automàticament a almenys la finestra de prova de Satoshi de 24 hores quan passes un `satoshi_deposit_address`. |

```json theme={null}
{
  "widget_session_id": "77777777-8888-9999-aaaa-bbbbbbbbbbbb",
  "token": "3s9x...urlsafe",
  "url": "https://verify.didit.me/wallet-ownership/3s9x...urlsafe",
  "expires_at": "2026-07-07T13:00:00Z"
}
```

Obre sempre la `url` retornada a la resposta tal com és; no la construeixis tu mateix.

### Obrir la URL retornada

> [!WARNING]
>
> **El widget només és web en aquesta versió. Obre la `url` al navegador del sistema o en una pestanya personalitzada; mai dins d'un webview del SDK mòbil de Didit.**
>
> La signatura de missatges funciona amb carteres instal·lades al navegador del client, que el widget descobreix mitjançant els protocols EIP-6963 i Wallet Standard.
> Actualment no està disponible la vinculació amb una aplicació de cartera mòbil separada, per exemple mitjançant un codi QR, de manera que el widget no passa el control a cap altra aplicació.
> Un webview integrat a l'aplicació, com el webview del SDK de Didit per a Web/Flutter/React Native/iOS/Android, **no pot accedir a les carteres del navegador del client**, de manera que un widget obert allà deixa el client sense manera de signar.
>
> En mòbil, inicia la `url` amb el navegador del sistema operatiu (`SFSafariViewController` / Chrome Custom Tabs, o el navegador per defecte) en lloc de mostrar-la en un webview. En web, una pestanya normal o una finestra emergent són correctes.

### Detectar la finalització

El widget exposa un endpoint de lectura públic identificat pel token: consulta'l periòdicament per veure el progrés, o confia en els webhooks quan la sessió està vinculada a una transferència:

```bash theme={null}
curl https://verification.didit.me/v3/travel-rule/widget/{token}/
```

```json theme={null}
{
  "vasp_name": "Origin CASP SL",
  "wallet_address": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9",
  "chain": "ETH",
  "holder_name": "Jane Doe",
  "allowed_methods": ["MESSAGE_SIGNING", "SCREENSHOT", "SATOSHI_TEST", "SELF_DECLARATION"],
  "transfer_status": "UNCONFIRMED_OWNERSHIP",
  "callback_url": "https://yourapp.example/wallet-verified",
  "expires_at": "2026-07-07T13:00:00Z",
  "completed_at": null,
  "proofs": [
    {
      "proof_id": "88888888-9999-aaaa-bbbb-cccccccccccc",
      "method": "SATOSHI_TEST",
      "status": "PENDING",
      "wallet_address": "0xd3b62acb76fb27a7f8961ec40fa11746b113aca9",
      "chain": "ETH",
      "deposit_address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
      "expected_amount": "0.000042817305521963",
      "expires_at": "2026-07-07T13:05:00.412731+00:00",
      "created_at": "2026-07-06T13:05:00.412731Z"
    }
  ],
  "customization": null
}
```

* `completed_at` passa a tenir valor no nul quan una prova es verifica.
* Cada entrada de `proofs` porta els camps que necessita el seu mètode: una prova `SATOSHI_TEST` afegeix `deposit_address`, `expected_amount` i el seu propi `expires_at`; una prova `MESSAGE_SIGNING` afegeix `challenge`, la cadena que signa el client.
* Una prova `SATOSHI_TEST` pot quedar amb `status: "PENDING"` mentre el seu dipòsit es veu a la cadena de blocs però encara no està confirmat, sense cap acció necessària per part teva ni del client; consulta [contracte de verificació de la prova Satoshi](#contracte-de-verificació-de-la-prova-satoshi) més amunt.
* Quan la sessió s'ha creat amb un `transaction_id`, verificar la prova fa avançar la transferència vinculada i, en una aplicació en producció, s'activa un webhook [`travel_rule.status.updated`](https://docs.didit.me/ca/integration/webhooks#tipus-d’esdeveniments).
  Prefereix el webhook a les consultes periòdiques.
  Una consulta `TRP` entrant s'aprova i es retorna al remitent, i passa a `COMPLETED` quan es lliura aquesta aprovació. Qualsevol altra transferència en `UNCONFIRMED_OWNERSHIP` (o una entrant en `ON_HOLD`) passa a `COMPLETED`, o a `COUNTERPARTY_MISMATCHED_DATA` quan el nom del beneficiari no coincideix amb el del titular de la cartera, i un dipòsit sunrise liquidat que es completa continua fins a `FINISHED`.
  Una transferència sortint en `COUNTERPARTY_VASP_NOT_FOUND` passa a `COMPLETED`.
* Una prova `SCREENSHOT` manté `status: "PENDING"` en aquest context, fins i tot després que confirmis la titularitat.
  L'aprovaràs amb [`POST .../travel-rule/ownership/`](https://docs.didit.me/ca/transaction-monitoring/travel-rule#confirmació-de-la-titularitat-de-la-cartera), que només accepta una transferència que espera la confirmació de la titularitat.
  Per tant, una captura de pantalla no té cap via d'aprovació en una sessió sense transferència vinculada, ni en una sessió vinculada a una transferència sortint en `COUNTERPARTY_VASP_NOT_FOUND`: desactiva `allow_screenshot_proof` si aquestes sessions no han d'oferir-la.
* Després d'una prova rebutjada, la sessió admet un nou intent mentre en queden. `max_attempts`, `attempts_used` i `attempts_remaining` indiquen el recompte, una prova rebutjada porta `rejection_reason`, i quan `attempts_remaining` és `0`, iniciar una altra prova respon amb `409` i has de crear una sessió nova.
* L'endpoint de context retorna `404` per a un token desconegut i `410` quan la sessió ha caducat sense completar-se.

> [!NOTE]
>
> Aquí no hi ha dependències d'un sol ús: el widget i el teu backend convergeixen en el mateix estat persistent (l'entrada verificada de la llibreta d'adreces i l'estat de la transferència), de manera que un webhook perdut o una pestanya tancada sempre es poden recuperar tornant a llegir la transferència o el context del widget.

## Localització i marca

El widget es mostra en **54 idiomes**, segons el camí d'idioma de l'enllaç (o l'idioma predeterminat del navegador).

Quan la marca blanca està activada per a la vostra aplicació, el widget hereta automàticament la marca del vostre flux de verificació: logotip, colors de marca, estil de botons i panells, tipus de lletra personalitzat, favicon i el nom públic de la vostra aplicació al títol.
No cal cap configuració addicional: s'aplica la mateixa personalització que heu configurat per a les sessions de KYC.

Un usuari que torna a un enllaç ja completat veu de nou la pantalla de finalització; si heu passat un `callback_url`, el widget hi redirigeix l'usuari.
Els enllaços caducats mostren una pantalla de caducitat amb la marca pròpia, que convida l'usuari a sol·licitar un enllaç nou.
Creeu una sessió nova amb `POST /v3/travel-rule/widget-session/` per a aquest usuari: reenviar una transferència amb `action: "resend"` no en crea cap.

## Propers passos

> [card] [Travel Rule](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md)
>
> El cicle de vida complet de l'intercanvi, els canals, la configuració i els fluxos de recepció.

> [card] [Llibreta d'adreces de carteres](https://docs.didit.me/ca/transaction-monitoring/travel-rule.md#llibreta-d’adreces-de-carteres)
>
> Registreu les carteres que controleu perquè les transferències entrants es puguin associar a aquestes carteres.

> [card] [Webhooks](https://docs.didit.me/ca/integration/webhooks.md)
>
> Subscriviu-vos a travel\_rule.status.updated per reaccionar quan una prova faci avançar una transferència.

> [card] [SDK natius](https://docs.didit.me/ca/integration/native-sdks/overview.md)
>
> Obriu l'URL del widget amb el navegador del sistema, no amb el webview de l'SDK.


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