Pular para o conteúdo principal
O widget de propriedade de carteira é uma página hospedada que comprova que um dos seus clientes controla um endereço específico de carteira cripto. Pelo TFR da UE, um VASP deve verificar a propriedade de uma carteira autocustodiada (não hospedada) antes de liberar fundos para ela ou a partir dela acima do limiar de sunrise. O widget é a forma como a Didit coleta essa prova sem que você precise criar fluxos de assinatura por conta própria. Uma prova verificada marca a entrada correspondente no catálogo de endereços de carteiras como is_ownership_verified: true, o que permite que uma transferência da Travel Rule vinculada saia de UNCONFIRMED_OWNERSHIP.

Quando a Didit cria a sessão para você

Raramente você precisa criar uma sessão por conta própria. Quando auto_wallet_verification está ativado nas suas configurações da Travel Rule (o padrão), a Didit cria automaticamente uma sessão do widget na criação da transação sempre que uma transferência exige que o usuário final comprove o controle da carteira:
  • A transferência está em UNCONFIRMED_OWNERSHIP: a carteira da contraparte foi declarada autocustodiada no envio.
  • A transferência é de saída e está em COUNTERPARTY_VASP_NOT_FOUND: nenhum VASP da contraparte pôde ser identificado, então a prova de propriedade é o caminho que resta para a conclusão.
A sessão criada automaticamente é retornada no bloco action_required da transação (type: "wallet_ownership", com a url a ser aberta), e os SDKs a abrem automaticamente no envio do lado do cliente. Transferências de entrada que a Didit cria para você (um registro de sunrise, uma consulta TRP de entrada ou o trecho de entrada pela via INTERNAL) nunca recebem uma sessão criada automaticamente, mesmo quando entram em UNCONFIRMED_OWNERSHIP. Crie a sessão manualmente com POST /v3/travel-rule/widget-session/ quando quiser verificar previamente uma carteira antes de existir qualquer transferência, quando tiver auto_wallet_verification desativado ou para uma dessas transferências de entrada.

O que ele comprova

O widget oferece até quatro métodos de comprovação. Quais deles aparecem depende de como você criou a sessão e das suas configurações da Travel Rule:

Contrato de verificação da assinatura de mensagem

O envio da assinatura retorna 200 com status: "VERIFIED" quando ela comprova o controle da carteira. Caso contrário, retorna 400 e mantém a comprovação aberta, para que o cliente possa assinar novamente, com um destes valores de code:

Contrato de verificação do teste de Satoshi

A verificação de um depósito do teste de Satoshi é assíncrona, porque a transação precisa ser vista on-chain e depois confirmada. O envio do txid do depósito retorna 200 com status: "PENDING" enquanto o depósito ainda não foi confirmado on-chain; o txid fica armazenado, não é descartado. Retorna 200 com status: "VERIFIED" quando o depósito é confirmado. Retorna 400 com status: "REJECTED" para um depósito realmente incorreto: enviado de outra carteira, com um valor diferente do esperado para o endereço de depósito, anterior ao desafio, ou uma transação que já comprovou outra carteira. A comprovação é encerrada e o cliente pode iniciar uma nova enquanto a sessão ainda tiver tentativas restantes. Um depósito que ainda não foi indexado também retorna 200 com status: "PENDING", e uma consulta que falha do lado da Didit retorna 400 com o código DEPOSIT_LOOKUP_FAILED: nos dois casos, a comprovação continua aberta e a Didit continua verificando. Retorna 410 se a janela do teste expirar antes de um depósito válido ser visto. Depois que um txid é enviado, um job em segundo plano verifica novamente o depósito pendente a cada cinco minutos e conclui a comprovação quando a transação é confirmada, então o cliente não precisa reenviar o txid. Quando você informa um satoshi_deposit_address, o próprio expires_at da sessão do widget é estendido para, no mínimo, a janela de 24 horas do teste de Satoshi, dando tempo para o depósito ser confirmado antes que a própria sessão expire.

Fluxo

1

Crie uma sessão do widget

Chame POST /v3/travel-rule/widget-session/ com a carteira que você precisa verificar. Opcionalmente, vincule-a a uma transferência para que a transferência avance automaticamente assim que a propriedade for comprovada.
2

Abra a URL retornada

Envie seu cliente para a url da resposta. Ele conclui uma prova ali, sem precisar de conta Didit nem de chave de API: o token na URL serve para autenticação.
3

Detecte a conclusão

Quando uma prova é verificada, o widget marca a entrada do catálogo de endereços como verificada e, se a sessão estiver vinculada a uma transferência, faz essa transferência avançar. Acompanhe travel_rule.status.updated (transferências vinculadas) ou consulte periodicamente o contexto do widget.

Crie uma sessão do widget

Este exemplo vincula a sessão à transferência autocustodiada declarada do guia de Travel Rule, então wallet_address é a carteira de destino dessa transferência. Uma sessão vinculada a uma transferência só aceita provas para a carteira da contraparte da transferência.
Sempre abra a url retornada na resposta exatamente como veio; não a monte você mesmo.

Abra a URL retornada

Nesta versão, o widget funciona apenas na web. Abra a url no navegador do sistema ou em uma custom tab, nunca dentro de uma webview de um SDK mobile da Didit.A assinatura de mensagem funciona com carteiras instaladas no navegador do cliente, que o widget detecta pelos protocolos EIP-6963 e Wallet Standard. Parear um app de carteira mobile separado, por exemplo por QR code, não está disponível hoje, então o widget não transfere o fluxo para outro app. Uma webview dentro do app, como a webview dos SDKs Web/Flutter/React Native/iOS/Android da Didit, não consegue acessar as carteiras do navegador do cliente, então um widget aberto ali deixa o cliente sem como assinar.No mobile, abra a url com o navegador do sistema operacional (SFSafariViewController / Chrome Custom Tabs, ou o navegador padrão) em vez de renderizá-la em uma webview. Na web, uma aba normal ou um popup funcionam bem.

Detecte a conclusão

O widget expõe um endpoint público de leitura identificado pelo token. Consulte-o periodicamente para ver o progresso ou use webhooks quando a sessão estiver vinculada a uma transferência:
  • completed_at deixa de ser nulo assim que uma prova é verificada.
  • Cada entrada em proofs traz os campos de que seu método precisa: uma prova SATOSHI_TEST acrescenta deposit_address, expected_amount e seu próprio expires_at; uma prova MESSAGE_SIGNING acrescenta challenge, a string que o cliente assina.
  • Uma prova SATOSHI_TEST pode ficar em status: "PENDING" enquanto seu depósito aparece on-chain sem confirmação, sem nenhuma ação necessária de você ou do cliente. Veja o contrato de verificação do teste de Satoshi acima.
  • Quando a sessão foi criada com um transaction_id, verificar a prova faz a transferência vinculada avançar e, em uma aplicação em produção, um webhook travel_rule.status.updated é disparado. Prefira o webhook à consulta periódica. Uma consulta TRP recebida é aprovada de volta para o remetente e passa para COMPLETED assim que essa aprovação é enviada. Qualquer outra transferência em UNCONFIRMED_OWNERSHIP (ou uma recebida em ON_HOLD) passa para COMPLETED, ou para COUNTERPARTY_MISMATCHED_DATA quando o nome do beneficiário não corresponde ao titular da carteira, e um depósito sunrise liquidado que seja concluído passa para FINISHED. Uma transferência enviada em COUNTERPARTY_VASP_NOT_FOUND passa para COMPLETED.
  • Uma prova SCREENSHOT mantém status: "PENDING" neste contexto mesmo depois que você confirma a propriedade. Você a aprova com POST .../travel-rule/ownership/, que só aceita uma transferência aguardando confirmação de propriedade. Por isso, uma captura de tela não tem como ser aprovada em uma sessão sem transferência vinculada, nem em uma sessão vinculada a uma transferência enviada em COUNTERPARTY_VASP_NOT_FOUND: desative allow_screenshot_proof se essas sessões não puderem oferecê-la.
  • Depois de uma prova rejeitada, a sessão aceita uma nova tentativa enquanto restarem tentativas. max_attempts, attempts_used e attempts_remaining informam a contagem, uma prova rejeitada traz rejection_reason e, quando attempts_remaining é 0, iniciar outra prova retorna 409 e você precisa criar uma nova sessão.
  • O endpoint de contexto retorna 404 para um token desconhecido e 410 quando a sessão expirou sem ser concluída.
Não há dependências que só possam ser executadas uma vez aqui: o widget e o seu backend convergem para o mesmo estado persistente (a entrada verificada do catálogo de endereços e o status da transferência), então a perda de um webhook ou o fechamento de uma aba são sempre contornáveis ao consultar novamente a transferência ou o contexto do widget.

Localização e identidade visual

O widget é exibido em 54 idiomas, conforme o idioma indicado no caminho do link (ou o padrão do navegador). Quando a marca própria está ativada para a sua aplicação, o widget herda automaticamente a identidade visual do seu fluxo de verificação: logotipo, cores da marca, estilo de botões e painéis, fonte personalizada, favicon e o nome público do seu app no título. Não há configuração separada: a mesma personalização que você definiu para as sessões de KYC vale aqui. Um usuário que volta a um link já concluído vê a tela de conclusão novamente; se você informou uma callback_url, o widget o redireciona para ela. Links expirados exibem uma tela de expiração com a sua identidade visual, incentivando o usuário a solicitar um novo link. Crie uma nova sessão para ele com POST /v3/travel-rule/widget-session/: reenviar uma transferência com action: "resend" não cria uma nova sessão.

Próximos passos

Travel Rule

O ciclo de vida completo da troca, os canais, as configurações e os fluxos de recebimento.

Agenda de endereços de carteiras

Registre as carteiras que você controla para que as transferências recebidas sejam associadas a elas.

Webhooks

Assine travel_rule.status.updated para reagir quando uma prova fizer com que uma transferência avance.

SDKs nativos

Abra a URL do widget no navegador do sistema, não na webview do SDK.
Última modificação em 1 de novembro de 2026