Saltar para o conteúdo principal
O widget de propriedade da carteira é uma página alojada que comprova que um dos seus clientes controla um endereço de carteira cripto específico. Ao abrigo do TFR da UE, uma VASP tem de verificar a propriedade de uma carteira autocustodiada (unhosted) antes de libertar fundos para ela ou a partir dela acima do limiar sunrise. O widget é a forma como a Didit recolhe essa prova, sem que tenha de criar os fluxos de assinatura por si. Uma prova verificada marca a entrada do livro de endereços de carteiras correspondente como is_ownership_verified: true, o que permite que uma transferência Travel Rule associada avance a partir de UNCONFIRMED_OWNERSHIP.

Quando a Didit o cria para si

Raramente precisa de criar uma sessão manualmente. Quando auto_wallet_verification está ativado nas suas definições da Travel Rule (o valor predefinido), a Didit cria automaticamente uma sessão do widget na criação da transação sempre que uma transferência precisa de prova de controlo da carteira pelo utilizador final:
  • A transferência está em UNCONFIRMED_OWNERSHIP, porque a carteira da contraparte foi declarada autocustodiada na submissão.
  • A transferência é de saída e está em COUNTERPARTY_VASP_NOT_FOUND, porque não foi possível identificar nenhuma VASP da contraparte, pelo que a prova de propriedade é o único caminho restante para a conclusão.
A sessão criada automaticamente é devolvida no bloco action_required da transação (type: "wallet_ownership", com o url a abrir), e os SDK iniciam-na automaticamente na submissão do lado do cliente. As transferências de entrada que a Didit cria para si (um registo sunrise, uma consulta TRP de entrada ou a perna de entrada do canal INTERNAL) nunca recebem uma sessão criada automaticamente, mesmo quando ficam em UNCONFIRMED_OWNERSHIP. Crie a sessão manualmente com POST /v3/travel-rule/widget-session/ quando quiser pré-verificar uma carteira antes de existir qualquer transferência, quando tiver auto_wallet_verification desativado ou para uma dessas transferências de entrada.

O que comprova

O widget oferece até quatro métodos de prova. Os que aparecem dependem da forma como a sessão foi criada e das suas definições da Travel Rule:

Contrato de verificação de assinatura de mensagens

Submeter a assinatura devolve 200 com status: "VERIFIED" assim que prova o controlo da carteira. Devolve 400 e deixa a prova aberta, para que o cliente possa assinar novamente, com um destes valores de code:

Contrato de verificação do teste Satoshi

A verificação de um depósito de teste Satoshi é assíncrona, porque a transação tem de ser vista on-chain e depois confirmada. Submeter o txid do depósito devolve 200 com status: "PENDING" enquanto o depósito ainda não estiver confirmado on-chain - o txid é retido, não descartado. Devolve 200 com status: "VERIFIED" assim que o depósito é confirmado. Devolve 400 com status: "REJECTED" para um depósito efetivamente errado: enviado de outra carteira, com um montante diferente do esperado para o endereço de depósito, anterior ao desafio, ou uma transação que já provou outra carteira. A prova fica fechada e o cliente pode iniciar uma nova enquanto a sessão tiver tentativas disponíveis. Um depósito que ainda não está indexado também devolve 200 com status: "PENDING", e uma consulta que falha do lado da Didit devolve 400 com o código DEPOSIT_LOOKUP_FAILED. Em ambos os casos a prova fica aberta e a Didit continua a verificar. Devolve 410 se a janela de teste expirar antes de ser visto um depósito válido. Depois de um txid ter sido submetido, uma tarefa em segundo plano volta a verificar o depósito pendente a cada cinco minutos e completa a prova depois de a transação ser confirmada. Assim, o cliente não precisa de submeter novamente o txid. Quando fornece um satoshi_deposit_address, o expires_at da própria sessão do widget é prolongado para pelo menos a janela de teste Satoshi de 24 horas, dando tempo ao depósito para ser confirmado antes de a sessão expirar.

Fluxo

1

Criar uma sessão do widget

Chame POST /v3/travel-rule/widget-session/ com a carteira que precisa de ser verificada. Opcionalmente, associe-a a uma transferência para que esta avance automaticamente assim que a propriedade for comprovada.
2

Abrir o URL devolvido

Envie ao seu cliente o url da resposta. Ele conclui ali uma prova, sem necessidade de conta Didit nem de chave de API; o token no URL é a autenticação.
3

Detetar a conclusão

Quando uma prova é verificada, o widget marca a entrada do livro de endereços como verificada e, se a sessão estiver associada a uma transferência, avança-a. Fique atento a travel_rule.status.updated (transferências associadas) ou faça polling ao contexto do widget.

Criar uma sessão do widget

Este exemplo associa a sessão à transferência declarada com carteira autocustodiada do guia da Travel Rule, pelo que wallet_address é a carteira de destino dessa transferência. Uma sessão associada a uma transferência só aceita provas para a carteira da contraparte da transferência.
Abra sempre o url devolvido na resposta tal como vem - não o construa você mesmo.

Abrir o URL devolvido

O widget só está disponível na web nesta versão. Abra o url no navegador do sistema ou num separador personalizado - nunca dentro de uma webview de um SDK móvel da Didit.A assinatura de mensagens funciona com carteiras instaladas no navegador do cliente, que o widget deteta através dos protocolos EIP-6963 e Wallet Standard. A associação a uma aplicação de carteira móvel separada, por exemplo por código QR, não está disponível atualmente, pelo que o widget não transfere o cliente para outra aplicação. Uma webview dentro da aplicação, como a webview do SDK Web/Flutter/React Native/iOS/Android da Didit, não consegue aceder às carteiras do navegador do cliente, pelo que um widget aberto aí deixa o cliente sem forma de assinar.Em dispositivos móveis, abra o url com o navegador do sistema operativo (SFSafariViewController / Chrome Custom Tabs, ou o navegador predefinido) em vez de o apresentar numa webview. Na web, um separador normal ou uma janela pop-up é adequado.

Detetar a conclusão

O widget expõe um endpoint público de leitura identificado pelo token - faça polling para ver o progresso, ou confie nos webhooks quando a sessão estiver associada a uma transferência:
  • completed_at passa a não ser nulo assim que uma prova é verificada.
  • Cada entrada em proofs traz os campos de que o seu método necessita: uma prova SATOSHI_TEST acrescenta deposit_address, expected_amount e o seu próprio expires_at; uma prova MESSAGE_SIGNING acrescenta challenge, a cadeia de caracteres que o cliente assina.
  • Uma prova SATOSHI_TEST pode ficar com status: "PENDING" enquanto o depósito é visto na blockchain mas ainda não está confirmado, sem qualquer ação necessária da sua parte nem da do cliente - veja o contrato de verificação do teste Satoshi acima.
  • Quando a sessão foi criada com um transaction_id, a verificação da prova avança a transferência associada e, numa aplicação em produção, dispara-se um webhook travel_rule.status.updated. Prefira o webhook ao polling. Um pedido TRP recebido é aprovado de volta ao remetente e passa a COMPLETED assim que essa aprovação for entregue. Qualquer outra transferência em UNCONFIRMED_OWNERSHIP (ou uma recebida em ON_HOLD) passa a COMPLETED, ou a 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 avança para FINISHED. Uma transferência enviada em COUNTERPARTY_VASP_NOT_FOUND passa a COMPLETED.
  • Uma prova SCREENSHOT mantém status: "PENDING" neste contexto, mesmo depois de confirmar a propriedade. Aprova-a com POST .../travel-rule/ownership/, que só aceita uma transferência a aguardar a confirmação de propriedade. Por isso, uma captura de ecrã não tem caminho de aprovação numa sessão sem transferência associada, nem numa sessão associada a uma transferência enviada em COUNTERPARTY_VASP_NOT_FOUND: desative allow_screenshot_proof se essas sessões não devem oferecê-la.
  • Após uma prova rejeitada, a sessão aceita uma nova tentativa enquanto restarem tentativas. max_attempts, attempts_used e attempts_remaining indicam a contagem, uma prova rejeitada inclui rejection_reason, e quando attempts_remaining for 0, iniciar outra prova responde com 409 e tem de criar uma nova sessão.
  • O endpoint de contexto devolve 404 para um token desconhecido e 410 quando a sessão expirou sem ter sido concluída.
Não há dependências de uso único aqui: o widget e o seu backend convergem para o mesmo estado durável (a entrada verificada do livro de endereços e o estado da transferência), pelo que um webhook perdido ou um separador fechado é sempre recuperável ao reler a transferência ou o contexto do widget.

Localização e marca

O widget é apresentado em 54 idiomas, seguindo o caminho de idioma da ligação (ou o idioma predefinido do navegador). Quando a marca branca está ativada para a sua aplicação, o widget herda automaticamente a personalização do seu fluxo de verificação: logótipo, cores da marca, estilo dos botões e do painel, tipo de letra personalizado, favicon e o nome público da sua aplicação no título. Não é necessária nenhuma configuração adicional: aplica-se a mesma personalização que configurou para as sessões de KYC. Um utilizador que volta a uma ligação já concluída volta a ver o ecrã de conclusão; se tiver passado um callback_url, o widget reencaminha-o para esse endereço. As ligações expiradas mostram um ecrã de expiração com a marca, que convida a pedir uma nova ligação. Crie uma nova sessão para essa pessoa com POST /v3/travel-rule/widget-session/: reenviar uma transferência com action: "resend" não cria uma sessão.

Próximos passos

Travel Rule

O ciclo de vida completo do intercâmbio, os canais, as definições e os fluxos de receção.

Livro de endereços de carteiras

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

Webhooks

Subscreva travel_rule.status.updated para reagir quando uma prova faz avançar uma transferência.

SDKs nativos

Abra o URL do widget com o navegador do sistema, e não com a webview do SDK.
Última modificação em 7 de novembro de 2026