How to Integrate DApps with a Blockchain Wallet Using WalletConnect 2.0

Β·

Integrating decentralized applications (DApps) with blockchain wallets is a critical step in building seamless Web3 experiences. This guide walks you through the complete process of connecting your DApp to a wallet using WalletConnect 2.0, focusing on secure communication, transaction handling, and user authentication.

Whether you're a developer building on Bitcoin SV or creating multi-chain applications, understanding how to properly interface with wallets ensures better usability, security, and adoption.

Core Integration Requirements

To begin integrating your DApp with a wallet via WalletConnect 2.0, ensure the following prerequisites are met:

πŸ‘‰ Discover how easy it is to start building secure DApp connections today.

Initialization

Initialize the WalletConnect client with proper configuration options:

await WalletConnectClient.init(
  Object.assign(
    {
      relayUrl: 'wss://your-relay-domain.com', // Replace with your relay server
    } as ClientOptions,
    opts ?? {}
  )
);

This sets up the secure bridge between your DApp and the user’s wallet using encrypted messaging over WebSockets.

Establishing Connection

Once initialized, initiate the connection request from the DApp side.

DApp Metadata Structure

Provide clear and concise metadata so users understand which application is requesting access:

FieldDescription
nameName of the DApp
descriptionBrief functionality overview
urlOfficial website URL
iconsArray of icon URLs for display

Use this structure when calling connect():

const wc = useWallet();
await wc.connect({
  name: 'My DApp',
  description: 'A decentralized marketplace',
  url: 'https://mydapp.example.com',
  icons: ['https://mydapp.example.com/icon.png']
});

Session Response Structure

Upon successful connection, the wallet returns session data in the following format:

bsv:livenet:alias|domain|address|signature

Breakdown:

Example:

bsv:livenet:test_account|chainbow.io|1BikvsWbVmLC9R9inrtRLQ7j2qBpMJVUfT|Hxj8kJ7ZdDC8zgtCAZopEQ01VUPI4Gl+L8L26IYKcsh/Mp1nhlxniTGFuPYTCPZMNA3ovlHdVED43r+QLiaYwmw=

If no alias exists:

bsv:livenet:| |1BikvsWbVmLC9R9inrtRLQ7j2qBpMJVUfT|signature

Signing Messages for Authentication

Securely verify user ownership of an address using message signing.

Request Structure

FieldDescription
addressWallet address to sign
messageMessage to be signed
await wc.signMessage({ address: data.address, message: data.message });

Response

Returns a cryptographic signature:

FieldDescription
signatureHex-encoded signed message

Verifying the Signature

Use standard libraries to validate authenticity:

const result = Message.verify(data.message, data.address, data.signature);
if (result) {
  console.log("Signature verified");
}

This confirms that the user controls the private key associated with the provided address.

Sending Transactions

Single Transaction: sendTransaction()

Send funds directly from the wallet using structured output parameters.

Input Structure

FieldDescription
toRecipient (address, Paymail, or script)
formatType: 'address', 'paymail', or 'script'
amountAmount in satoshis
await wc.sendTransaction({
  outputs: [
    {
      to: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
      format: 'address',
      amount: '10000'
    }
  ]
});

Response

FieldDescription
txIdTransaction ID
timeTimestamp (ms)
feeNetwork fee (satoshi)
amountSent amount (satoshi)

Example:

{
  "txId": "91256db99f8756d757fa72f2bf57b6c2bb45e9ce2d6e4a5d78ff70d89b6d53c9",
  "time": 1645501589365,
  "fee": 200,
  "amount": 600
}

πŸ‘‰ Learn how to streamline blockchain transactions in your DApp now.

Multiple Transactions: sendRawTransaction()

Broadcast pre-signed raw transactions to the network.

Input

FieldDescription
rawHexFull serialized transaction hex
const res = await wc.sendRawTransaction([rawHex]);

Response

Returns only:

Ideal for batch operations or complex smart contract interactions where signing logic occurs off-wallet.

Signing Custom Transactions

For advanced use cases like multi-signature or conditional payments, request partial signatures.

Input: ITransaction & Sign Requests

Transaction Inputs

FieldDescription
prevTxIdPrevious transaction ID
outputIndexOutput index
satoshisValue in satoshis
lockingScriptScriptPubKey as hex

Transaction Outputs

FieldDescription
toUnlocking script (e.g., P2PKH script hex)
formatMust be 'script'
amountOutput value

Sign Requests Array

FieldDescription
inputIndexIndex of input to sign
addressAssociated Bitcoin address
sigtypeHash type flags (e.g., SIGHASH_ALL)
const request = {
  transaction: { inputs, outputs },
  signRequests: [
    {
      inputIndex: 0,
      address: '1BikvsWbVmLC9R9inrtRLQ7j2qBpMJVUfT',
      sigtype: bsv.crypto.Signature.SIGHASH_ALL | bsv.crypto.Signature.SIGHASH_FORKID
    }
  ]
};
await wc.signTransaction(request);

Signature Response

Returns an array of signed inputs:

FieldDescription
prevTxIdReference transaction ID
outputIndexOutput position
satoshisAmount
sequenceNumberInput sequence
signatureDER-encoded signature
pubkeyPublic key used
sigtypeSignature hash flag
inputIndexIndex in transaction inputs

Example:

"signatures": [
  {
    "prevTxId": "35a7c737b2e39b7b81219cc1628402a795e7e8a48b6e940207b912123f5e43c1",
    "outputIndex": 0,
    "satoshis": 1280900,
    "sequenceNumber": 4294967295,
    "signature": "304402206738aafa8df6179e2511a08b9646db1c6957d25a48f20134704ef7e84d7c25e1...",
    "pubkey": "03753e4161e7dab8ca0de4350004af544ced8cdd17494df6597d4f7c12e3e0ed2a",
    "sigtype": 65,
    "inputIndex": 0
  }
]

Error Handling

Handle common errors gracefully to improve UX.

Error CodeMeaning
Error: User rejected the requestUser denied authorization
Error: UnknownAddressInvalid Bitcoin address format
Error: Session not approveSession login rejected
Error: JSON-RPC Request timeout...No response within 300 seconds

Implement retry logic and user prompts based on these codes.


Frequently Asked Questions (FAQ)

Q: Can I use WalletConnect 2.0 for non-BSV blockchains?
A: Yes. While this guide focuses on BSV integration, WalletConnect 2.0 supports multiple chains and namespaces, enabling cross-chain DApp development.

Q: Is user data exposed during connection?
A: No. All communication is end-to-end encrypted. The wallet only shares minimal required data like address and signed messages.

Q: What happens if the relay server goes down?
A: WalletConnect uses redundant relays and fallback mechanisms. Consider hosting your own relay for high availability.

Q: How do I test my integration before going live?
A: Use testnet networks and mock wallets. You can also clone example projects like DAppDemo for reference implementations.

Q: Are Paymail addresses mandatory?
A: No. They are optional but recommended for improved user experience and human-readable identifiers.

Q: Can I send tokens as well as satoshis?
A: Yes, provided the wallet and chain support token standards (e.g., BSV's Tokenized protocol). Adjust output formatting accordingly.


πŸ‘‰ Get started with secure, scalable DApp-wallet integration now.