Skip to content

Self-hosted wallet verification

Self-hosted wallet verification is the process of confirming ownership of a blockchain wallet address. This verification may be required before transferring virtual assets from a Virtual Asset Service Provider (VASP) to a non-custodial or self-hosted wallet. By implementing this process, VASPs can ensure that users are sending assets from their centralized accounts to wallets they personally own.

CryptoSwift supports the following wallet verification methods:

  • Cryptographic Signature Proofs
  • Micro Transactions (also known as the Satoshi test)
  • Wallet Screenshots
  • Self-Declaration

Cryptographic Signature Proofs

Cryptographic signature proofs are widely recognized as the industry standard for verifying wallet ownership. This method involves the user signing an off-chain message using their private keys, which can then be validated against their blockchain address. This process provides cryptographic assurance that the user controls the private keys for the wallet to which they intend to transfer funds.

CryptoSwift strongly advocates for the use of open-source, industry-standard solutions for signature proofs. Among the available options, Wallet Connect (now known as Reown) stands out as the most robust solution, offering the broadest wallet compatibility. It supports over 450 different wallets across different networks (Bitcoin, Etherum, Solana, Optimism, Arbitrum, Base, Polygon, BNB, Avalance and Cosmos among others). You can see the list of all supported wallets here.

Visit Reown or explore Reown docs to get started.

Integration

You can currently set up a direct integration with Reown to store the verification data for a self-hosted wallet.

Integration with Reown

Also see the web based Wallet Connect demo.

Once the verification successfully completed, you should send a request to CryptoSwift API:

curl --location 'https://api.cryptoswift.eu/wallet-verification/signature-proof' \
--header 'x-api-key: a70fcedf-416b-4f83-845c-a05aba0d7da4' \
--header 'Content-Type: application/json' \
--data '{
    "withdrawalAddress": "0x4f3C28bC79Aa124Fb0A7e52c3EeE5729D78D46aF",
    "withdrawalMetadata": "Any related metadata",
    "asset": "ETH",
    "signedMessage": "I confirm that this non-custodial wallet is mine",
    "signature": "q7XUz9XJbWjK9YO2iA8eW3OmEDCuqKDG12tzmPVNlDb9X6G6MxwGqv8J8B4gEZq43vU3D9VaGRKqB1wnyCrR7A="
}'

The request must contain the next mandatory data:

  • withdrawalAddress - Self hosted wallet address to verify
  • asset - The virtual asset.
  • signedMessage - The original message that was signed to prove ownership of the wallet address. This must be exactly the same as what the user signed.
  • signature - The cryptographic signature generated by signing the above message with the private key of the wallet address.

The request may contain the next optional data:

  • withdrawalMetadata - Self hosted wallet metadata that can be used to identify the wallet or user outside of the CryptoSwift system

Please refer to API documentation for more details.

Other blockchains

For self-hosted wallets that Wallet Connect does not support (like different bitcoin wallets), but that support user-supplied signatures, a custom implementation can be set up using the AOPP protocol.

See our AOPP implementation guide for more details.

Micro Transactions (Satoshi test)

A Satoshi test is a verification method where a specific amount of cryptocurrency is sent from the destination wallet address within a designated time frame to verify ownership and control of the wallet's private keys. The CryptoSwift API has support for micro transactions/Satoshi test.

Please make sure to setup a webhook before initiating the Satoshi test verification.

In order to initiate a Satoshi test wallet address verification:

1. Send a verification request

curl --location 'https://api.cryptoswift.eu/wallet-verification/satoshi-test' \
--header 'x-api-key: a70fcedf-416b-4f83-845c-a05aba0d7da4' \
--header 'Content-Type: application/json' \
--data '{
    "withdrawalAddress": "BsRdeZ75szhDiGN8hJs8v8PcqwBm7KsFcp",
    "withdrawalMetadata": "505b5625-fd42-4c03-911b-2310ea14b76a",
    "depositAddress": "C55oii4osxSKhER2NCMRoGYmCV7hcAdhLL",
    "asset": "BTC"
}'

The request must contain the next mandatory data:

  • withdrawalAddress - Self hosted wallet address to verify
  • depositAddress - VASP deposit wallet address
  • asset - The virtual asset. Must be from the list of supported assets: BTC, DASH, DOGE, LTC

The request may contain the next optional data:

  • amount - The amount to be transferred to depositAddress for verification. If not provided, CryptoSwift will generate a random amount between 1 and 100 of the lowest non-divisible unit on the blockchain for the request.
  • withdrawalMetadata - Self hosted wallet metadata that can be used to identify the wallet or user outside of the CryptoSwift system

2. Share the verification details with wallet owner

The response will contain the next crucial data:

  • verificationRequestId - The ID of the wallet verification request
  • asset - The virtual asset.
  • amount - The amount to be transferred to depositAddress for verification.
  • withdrawalAddress - Self hosted wallet address to verify
  • withdrawalMetadata - Self hosted wallet metadata that can be used to identify the wallet or user outside of the CryptoSwift system
  • depositAddress - VASP deposit wallet address
  • status - The status of the wallet verification: PENDING, VERIFIED, FAILED, DELETED
  • statusReasoning - Self hosted wallet verification status reasoning
  • verifiedTransactionHash - Self hosted wallet verification transaction hash
  • createdAt - When self hosted wallet verification been created
  • updatedAt - When self hosted wallet verification been updated

Share the depositAddress, asset and amount with wallet owner and kindly ask to make a transaction. Please note that the verification will be considered expired after 48 hours since the createdAt timestamp.

CryptoSwift will monitor the blockchain for a transaction with this specific details and notify you via a webhook.

3. Receive notification via webhook

The request from CryptoSwift will contain the next header: X-Event-Type: 'wallet-verification' and it may trigger due to verification expiry or due to successful verification case.

Example of a successful Satoshi test verification, the request body will contain the next data:

{
    ...
    "verificationRequestId": "53c8264f-5632-4ed2-b93e-42aa0bcd5830",
    "status": "VERIFIED",
    "verifiedTransactionHash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    ...
}

A successful Satoshi test verification will contain verifiedTransactionHash which you can use as a proof.

Please refer to API documentation for more details.

Wallet Screenshots

The CryptoSwift API supports wallet screenshots as a method for proof of ownership.

In order to initiate a self-declared wallet verification request:

1. Send a verification request

curl --location 'https://api.cryptoswift.eu/wallet-verification/visual-proof' \
--header 'x-api-key: a70fcedf-416b-4f83-845c-a05aba0d7da4' \
--form 'file=@"../Visual Proof.pdf"' \
--form 'withdrawalAddress="bc1q7jxz3fgnzm9wp6t8qn8ekq09l8gwux5zft90je"' \
--form 'asset="ETH"'

The request must contain the next mandatory data:

  • file - Visual proof file of type jpeg, png, jpg or pdf with the size limit of up to 5MB
  • withdrawalAddress - Self hosted wallet address to verify
  • asset - The virtual asset

The request may contain the next optional data:

  • withdrawalMetadata - Self hosted wallet metadata that can be used to identify the wallet or user outside of the CryptoSwift system

2. Approve the verification request

curl --location --request PATCH 'https://api.cryptoswift.eu/wallet-verification/2770f7b9-3397-44d7-88c7-d7642be38329' \
--header 'x-api-key: a70fcedf-416b-4f83-845c-a05aba0d7da4' \
--header 'Content-Type: application/json' \
--data '{"status":"VERIFIED", "statusReasoning": "Manual approval", "withdrawalMetadata": "Any related metadata" }'

The request must contain the next mandatory data:

  • status - Wallet Verification status PENDING, VERIFIED, FAILED or DELETED

The request may contain the next optional data:

  • withdrawalMetadata - Self hosted wallet metadata that can be used to identify the wallet or user outside of the CryptoSwift system
  • statusReasoning - Self hosted wallet verification status reasoning

Please refer to API documentation for more details.

Self-Declaration

CryptoSwift offers a self-declaration (checkbox) option, allowing users to confirm that they are the rightful owners of the self-hosted wallet address.

In order to initiate a self-declared wallet verification request, send a request:

curl --location 'https://api.cryptoswift.eu/wallet-verification/self-declared' \
--header 'x-api-key: a70fcedf-416b-4f83-845c-a05aba0d7da4' \
--header 'Content-Type: application/json' \
--data '{
    "withdrawalAddress": "BsRdeZ75szhDiGN8hJs8v8PcqwBm7KsFcp",
    "withdrawalMetadata": "05b5625-fd42-4c03-911b-2310ea14b76a",
    "approved": true,
    "asset": "BTC"
}'

The request must contain the next mandatory data:

  • withdrawalAddress - Self hosted wallet address to verify
  • depositAddress - VASP deposit wallet address
  • asset - The virtual asset
  • approved - A boolean declaration (TRUE) that confirms ownership of the wallet

The request may contain the next optional data:

  • withdrawalMetadata - Self hosted wallet metadata that can be used to identify the wallet or user outside of the CryptoSwift system

The request will be considered verified immediately.

Please refer to API documentation for more details.