Vai al contenuto principale
Il widget di verifica della proprietà del wallet è una pagina ospitata che dimostra che uno dei tuoi clienti controlla un determinato indirizzo di wallet crypto. Ai sensi del TFR dell’UE, un VASP deve verificare la proprietà di un wallet in autocustodia (unhosted) prima di inviare o ricevere fondi da quel wallet, se l’importo supera la soglia sunrise. Il widget è lo strumento con cui Didit raccoglie questa prova, senza che tu debba sviluppare da zero i flussi di firma. Una prova verificata contrassegna la corrispondente voce della rubrica degli indirizzi wallet come is_ownership_verified: true, il che consente a un trasferimento Travel Rule collegato di uscire da UNCONFIRMED_OWNERSHIP.

Quando Didit lo genera per te

Raramente hai bisogno di generare una sessione manualmente. Quando auto_wallet_verification è attivo nelle tue impostazioni Travel Rule (impostazione predefinita), Didit genera automaticamente una sessione del widget alla creazione della transazione, ogni volta che un trasferimento richiede la prova del controllo del wallet da parte dell’utente finale:
  • Il trasferimento è in UNCONFIRMED_OWNERSHIP: il wallet della controparte è stato dichiarato in autocustodia al momento dell’invio.
  • Il trasferimento è in uscita e si trova in COUNTERPARTY_VASP_NOT_FOUND: non è stato possibile identificare alcun VASP della controparte, quindi la prova della proprietà è l’unica via rimasta per il completamento.
La sessione generata automaticamente viene restituita nel blocco action_required della transazione (type: "wallet_ownership", con l’url da aprire), e gli SDK la avviano automaticamente all’invio lato client. I trasferimenti in entrata che Didit crea per te (una registrazione sunrise, una richiesta TRP in entrata o il ramo in entrata del canale INTERNAL) non ricevono mai una sessione generata automaticamente, anche quando finiscono in UNCONFIRMED_OWNERSHIP. Genera manualmente una sessione con POST /v3/travel-rule/widget-session/ quando vuoi pre-verificare un wallet prima che esista qualsiasi trasferimento, quando auto_wallet_verification è disattivato, oppure per uno di questi trasferimenti in entrata.

Cosa dimostra

Il widget offre fino a quattro metodi di prova. Quali compaiono dipende da come hai creato la sessione e dalle tue impostazioni Travel Rule:

Contratto di verifica per la firma del messaggio

L’invio della firma restituisce 200 con status: "VERIFIED" quando dimostra di controllare il wallet. Restituisce 400 e lascia la prova aperta, così il cliente può firmare di nuovo, con uno di questi valori di code:

Contratto di verifica del test Satoshi

La verifica di un deposito del test Satoshi è asincrona, perché la transazione deve essere vista on-chain e poi confermata. L’invio del txid del deposito restituisce 200 con status: "PENDING" finché il deposito non è ancora confermato on-chain - il txid viene conservato, non scartato. Restituisce 200 con status: "VERIFIED" quando il deposito viene confermato. Restituisce 400 con status: "REJECTED" per un deposito realmente errato: inviato da un altro wallet, con importo diverso da quello atteso verso l’indirizzo di deposito, più vecchio della challenge, oppure una transazione che ha già dimostrato un altro wallet. La prova viene chiusa e il cliente può avviarne una nuova finché la sessione ha tentativi disponibili. Un deposito non ancora indicizzato restituisce anch’esso 200 con status: "PENDING", e una ricerca non riuscita lato Didit restituisce 400 con codice DEPOSIT_LOOKUP_FAILED: in entrambi i casi la prova resta aperta e Didit continua a controllare. Restituisce 410 se la finestra del test scade prima che venga rilevato un deposito valido. Una volta inviato un txid, un job in background ricontrolla il deposito in attesa ogni cinque minuti e completa la prova dopo la conferma della transazione, quindi il cliente non deve inviare di nuovo il txid. Quando passi un satoshi_deposit_address, il valore expires_at della sessione del widget viene esteso ad almeno la finestra di 24 ore del test Satoshi, così il deposito ha tempo di confermarsi prima che scada la sessione.

Flusso

1

Genera una sessione widget

Chiama POST /v3/travel-rule/widget-session/ con il wallet da verificare. Facoltativamente, collegalo a un trasferimento, così il trasferimento avanza automaticamente una volta dimostrata la proprietà.
2

Apri l'URL restituito

Indirizza il cliente all’url della risposta. Lì completa una prova: non servono un account Didit né una chiave API, perché il token nell’URL è l’autenticazione.
3

Rileva il completamento

Quando una prova viene verificata, il widget contrassegna la voce della rubrica degli indirizzi come verificata e, se la sessione è collegata a un trasferimento, lo fa avanzare. Osserva travel_rule.status.updated (per i trasferimenti collegati) oppure interroga il contesto del widget.

Genera una sessione widget

Questo esempio collega la sessione al trasferimento dichiarato verso un wallet in autocustodia della guida Travel Rule, quindi wallet_address è il wallet di destinazione di quel trasferimento. Una sessione collegata a un trasferimento accetta solo prove relative al wallet della controparte del trasferimento.
Apri sempre l’url restituito nella risposta così com’è: non costruirlo tu.

Apri l’URL restituito

Il widget in questa release funziona solo sul web. Apri l’url nel browser di sistema o in una scheda personalizzata, mai all’interno di una webview di un SDK mobile di Didit.La firma dei messaggi funziona con i wallet installati nel browser del cliente, che il widget rileva tramite i protocolli EIP-6963 e Wallet Standard. L’associazione di un’app wallet mobile separata, ad esempio tramite codice QR, oggi non è disponibile, quindi il widget non passa a un’altra app. Una webview integrata nell’app, come la webview degli SDK Didit Web/Flutter/React Native/iOS/Android, non può raggiungere i wallet del browser del cliente, quindi un widget aperto lì lascia il cliente senza modo di firmare.Su mobile, avvia l’url con il browser del sistema operativo (SFSafariViewController / Chrome Custom Tabs, oppure il browser predefinito) invece di mostrarlo in una webview. Sul web, una scheda normale o un popup vanno bene.

Rileva il completamento

Il widget espone un endpoint di lettura pubblico identificato dal token: interrogalo per vedere l’avanzamento, oppure affidati ai webhook quando la sessione è collegata a un trasferimento:
  • completed_at diventa non nullo non appena una prova viene verificata.
  • Ogni voce in proofs contiene i campi richiesti dal suo metodo: una prova SATOSHI_TEST aggiunge deposit_address, expected_amount e il proprio expires_at; una prova MESSAGE_SIGNING aggiunge challenge, la stringa che il cliente firma.
  • Una prova SATOSHI_TEST può restare in status: "PENDING" mentre il suo deposito è visto on-chain ma non ancora confermato, senza alcuna azione richiesta né a te né al cliente: vedi contratto di verifica del test Satoshi sopra.
  • Quando la sessione è stata generata con un transaction_id, la verifica della prova fa avanzare il trasferimento collegato e, su un’applicazione in produzione, parte il webhook travel_rule.status.updated. Preferisci il webhook al polling. Una richiesta TRP in entrata viene approvata e restituita al mittente, e passa a COMPLETED non appena l’approvazione viene consegnata. Qualsiasi altro trasferimento in UNCONFIRMED_OWNERSHIP (o un trasferimento in entrata ON_HOLD) passa a COMPLETED, oppure a COUNTERPARTY_MISMATCHED_DATA quando il nome del beneficiario non corrisponde al titolare del wallet. Un deposito sunrise regolato che si completa prosegue fino a FINISHED. Un trasferimento in uscita in COUNTERPARTY_VASP_NOT_FOUND passa a COMPLETED.
  • Una prova SCREENSHOT resta in status: "PENDING" in questo contesto anche dopo che confermi la proprietà. La approvi con POST .../travel-rule/ownership/, che accetta solo un trasferimento in attesa di conferma della proprietà. Uno screenshot quindi non ha alcun percorso di approvazione su una sessione senza trasferimento collegato, oppure su una sessione collegata a un trasferimento in uscita in COUNTERPARTY_VASP_NOT_FOUND: disattiva allow_screenshot_proof se in quelle sessioni non deve essere offerto.
  • Dopo una prova rifiutata, la sessione consente un nuovo tentativo finché restano tentativi. max_attempts, attempts_used e attempts_remaining riportano il conteggio, una prova rifiutata contiene rejection_reason, e quando attempts_remaining è 0 avviare un’altra prova restituisce 409 e devi generare una nuova sessione.
  • L’endpoint del contesto restituisce 404 per un token sconosciuto e 410 quando la sessione è scaduta senza essere completata.
Qui non ci sono dipendenze una tantum: il widget e il tuo backend convergono sullo stesso stato durevole (la voce della rubrica verificata e lo stato del trasferimento). Quindi un webhook perso o una scheda chiusa si recuperano sempre rileggendo il trasferimento o il contesto del widget.

Localizzazione e branding

Il widget viene visualizzato in 54 lingue, in base alla lingua indicata nel link (oppure la lingua predefinita del browser). Quando il White label è attivo per la tua applicazione, il widget eredita automaticamente il branding del flusso di verifica: logo, colori del brand, stile di pulsanti e pannelli, font personalizzato, favicon e il nome pubblico della tua app nel titolo. Non serve alcuna configurazione aggiuntiva: si applica la stessa personalizzazione che hai impostato per le sessioni KYC. Un utente che torna a un link già completato vede di nuovo la schermata di completamento; se hai passato un callback_url, il widget lo riporta lì. I link scaduti mostrano una schermata di scadenza con il tuo brand, che invita l’utente a richiederne uno nuovo. Crea una nuova sessione per l’utente con POST /v3/travel-rule/widget-session/: reinviare un trasferimento con action: "resend" non ne crea una.

Prossimi passi

Travel Rule

Il ciclo di vita completo dello scambio, i canali, le impostazioni e i flussi di ricezione.

Rubrica degli indirizzi wallet

Registra i wallet che controlli, così i trasferimenti in entrata vengono associati a questi wallet.

Webhook

Iscriviti a travel_rule.status.updated per reagire quando una prova fa avanzare un trasferimento.

SDK nativi

Apri l’URL del widget con il browser di sistema, non con la webview dell’SDK.
Ultima modifica il 7 novembre 2026