Skip to content
Clav

How to prove self-custody wallet ownership as required by BCB Resolution 521

Art. 76-A, § 5 of BCB Resolution 277 requires Brazilian VASPs to identify the owner of a self-custody wallet. See what the rule asks for and how Clav handles it with a signature from the customer.

Eduardo de Paiva Gomes

When a customer asks to withdraw to an external wallet, the virtual asset service provider (VASP, or PSAV in Brazil) knows which address the asset is going to. It usually does not know who controls that address: it could be the customer, a third party or someone who borrowed the customer’s phone for five minutes. For part of these operations, BCB Resolution 521/2025 now requires the VASP to identify the wallet’s owner.

What the rule says

BCB Resolution 521, of 10 November 2025, added art. 76-A to BCB Resolution 277/2022. The article brings some activities of virtual asset service providers into the Brazilian FX market, including the “transfer of a virtual asset to or from a self-custody wallet that does not involve an international payment or transfer with virtual assets” (item III). The regulations are published in Portuguese; the quotes here are our translation.

For these operations, § 5 says:

The virtual asset service provider must identify the owner of a self-custody wallet, and implement and document processes to verify the origin and destination of virtual assets in the operations covered by the caput.

The same article defines a self-custody wallet as “one whose owner holds control of the respective private key and can move it without the participation of a virtual asset service provider”.

Why a customer statement falls short

The rule requires identifying the owner but does not say how. The cheapest option is to ask the customer to tick a box saying “this wallet is mine”. But a statement does not show that whoever filled it in controls the private key, and control of the key is exactly what the resolution uses to define the owner.

That control can be proven without asking the customer for anything sensitive, using a cryptographic signature. Whoever holds the private key can sign a message with it, and anyone can check, from the address, that the signature came from that key. Signing costs no network fee, moves no funds and gives nobody access to the wallet.

If the Banco Central asks how the VASP identified the owner of a wallet, having kept the signed message, the method and the date of the proof is a far stronger answer than a ticked box.

How Clav handles it

The screens below come from a demo organization, Example Exchange, verifying a wallet from start to finish.

1. The VASP opens a request

In Verified wallets, the team clicks Verify a wallet and fills in three fields: the customer identifier in the VASP’s own system, the network and the address.

The Verify a wallet dialog with the customer identifier, the EVM network and the address filled in.

Clav generates the message to be signed and returns a link. The team copies the link and sends it to the customer through the channel it already uses. The same can be done through the API, without the dashboard.

The generated verification link, with the Copy button and its expiry time.

2. The customer signs

The link opens a page that shows the VASP’s name prominently, so the customer recognizes who is asking. The page shows the network and the address, explains that signing costs nothing and warns that nobody will ever ask for the recovery phrase. The customer taps Connect wallet and signs, with no account and no login.

3. Clav checks and stores the proof

Clav checks the signature against the address. If it matches, the customer sees the confirmation right away and the address becomes a verified wallet. If it does not, the request ends as failed and the reason is recorded.

On a phone, the signing page with the Connect wallet button and, next to it, the Wallet verified confirmation.

4. The VASP checks before releasing the withdrawal

In the dashboard, the wallet shows up in the list with its network, customer, method and verification date.

The verified wallets list with the wallet of customer-8842 marked Active.

At withdrawal time, the VASP’s system asks Clav whether that address is verified. The answer already accounts for revocations made after the proof.

What gets recorded

Each verified wallet keeps the signed message, the signature, the address recovered from it and the full trail of the request. Issuance, attempts, approval, failure and revocation become immutable events the team can look up in the platform at any time.

The proof detail, with the signed message, the signature and the event trail of the request.

Sometimes a signature is valid but comes from a different address. In that case Clav records the address that actually signed, which helps an anti-money laundering investigation figure out who was on the other side.

If the customer stops using an address, the VASP revokes the wallet. The old proof stays on record as revoked, with the reason, and the withdrawal check reports the address as not verified until the customer proves it again.

Clav receives no personal data in this flow. The VASP sends only a customer identifier that makes sense in its own system, and the customer’s name and tax ID stay where they were.

For the end customer

The request arrives as a link, through the channel the VASP already uses with the customer. The page shows the VASP’s brand, the network and the address to be proven, and offers more than one path:

  • connect the wallet through WalletConnect, for compatible mobile and browser wallets;
  • sign manually, for hardware wallets or command-line tools: the person copies the message, signs it elsewhere and pastes the result;
  • on Bitcoin, send a micro-transaction of an exact amount, between 546 and 2,000 satoshis, for wallets that cannot sign messages.

Supported networks are Ethereum, Polygon, Arbitrum, Optimism, Base, BNB Smart Chain, Avalanche, Bitcoin, Solana and Tron, mainnet only.

For the VASP’s team

You can start with no integration: the flow in the screens above runs entirely from the dashboard, and that is enough for a pilot.

When automation pays off, the integration is a REST API with three main calls: open the request, follow the result and check the address before the withdrawal. The API key has its own scope for wallets and only sees data from the organization that owns it.

GET /v1/wallets?chain=EVM&address=0x5b38da6a701c568545dcfcb03fcb875f56beddc4

The response includes a verified field, and that is what decides whether the withdrawal goes out. Instead of polling each request, the VASP can subscribe to the wallet.verified and wallet.failed webhooks and get the result as soon as it is ready. Each call is described in the wallet verification documentation.

The result

Before every withdrawal to an external wallet, the VASP knows whether the customer proved control of that address and keeps the proof on file for an inspection. The customer signs one message and carries on with the withdrawal.

Section 5 asks for more than identifying the owner, though. It also requires documented processes to verify the origin and destination of the assets. Wallet verification covers the identification and serves as evidence for that process; the rest belongs to the VASP’s AML policy, which Clav helps organize in its compliance module.

How to enable it

Wallet verification is enabled per organization. If you already use Clav and do not see the Verified wallets menu, contact our team.