Decentralised Finance (DeFi) is redefining the utility of financial services by opening up access to lending, trading, and yield generating without relying on traditional intermediaries. To execute on DeFi strategies, seamless wallet connectivity is essential. To make this possible, Fireblocks has integrated with WalletConnect. In this blog, we’ll outline how the team has approached investigating issues related to WalletConnect sessions.
About WalletConnect
WalletConnect is an open-source protocol that allows for secure connections between digital asset wallets and dApps. Fireblocks customers can connect their vault accounts to thousands of dApps across dozens of blockchains via WalletConnect. The wallet can be a mobile application, a browser application, or an application server (cloud wallet).
How the WalletConnect handshake works
A wallet and a dApp that are connected to each other via WalletConnect can send messages back and forth via a Relay Network, a publish-subscribe network that routes messages between clients subscribed to a Relay Server (in this case, the server is managed by Reown, previously WalletConnect).
The wallet and dApp communicate with the Relay Server via JSON-RPC, which is documented here. When the wallet and dApp connect, two key data items are chosen. One is an identifier called a pairing topic, and the other is a symmetric key used to encrypt and decrypt subsequent messages. This is done to ensure a secure connection between the wallet and dApp, denying the WalletConnect relay server awareness of the contents of the messages it transmits.
Decrypting WalletConnect messages
At Fireblocks, one of the ways we enable our users to interact with external decentralized applications, such as exchanges, marketplaces, or other Web3 applications, is over the WalletConnect protocol.
Occasionally, our clients run into some bugs. First, we determine if the problem is in our system, or if it is an issue with the dApp.We do this by checking the websocket activity in our browser’s dev console to validate:
- Is what we see on our receiving end the same as what the dApp actually sent?
- Is the dApp sending a message which we are not receiving?
- If so, what is the content of that message?
However, the content is encrypted (as mentioned above) so let’s walk through the process of finding WalletConnect messages sent to and from the dApp, finding the symmetric key, and decrypting the messages.
Finding WalletConnect messages in the browser console
Let’s connect Fireblocks to Raydium and track the messages that are passed to and from Raydium via websocket. First, we’ll open the dApp (https://raydium.io/swap/), and then open the browser’s dev console (on Chrome, right click > “Inspect”). Now, we’ll choose the “Network” tab of the dev console and filter on “WS”. We shouldn’t see anything there yet.
On the Raydium UI, we click “Connect Wallet” > “WalletConnect”, and choose Fireblocks in the WalletConnect modal. Now we can see some websocket connections pop up in the dev console. The WalletConnect connections will start with “?auth=”. Choose one and then select the “Messages” tab.
We can select each message and view its JSON contents in an organized format. Let’s start with the first one.
The green up arrow next to the message in the messages tab indicates that this is an outgoing message – it was sent from the dApp to the Relay Server. The irn_subscribe method type indicates that the dApp is subscribing to messages from the Server on a new topic (refer to the WalletConnect Relay Server RPC documentation). The topic is included in the params. This type of message has nothing for us to decode.
Let’s skip down to the first message with the irn_publish method type.
This message is also outgoing from the dApp to the server. We can see some new fields in the params object now. If we decode the message, it will reveal what the dApp is trying to send to the wallet.
To do this, we will first need to use the topic to find the symmetric key.
Finding the symmetric key in the browser console
In the dev console, switch from the “Network” tab to the “Application” tab. On the left, under the “Storage” heading, select “IndexedDB” > “WALLET_CONNECT_V2_INDEXED_DB” > “keyvaluestorage”.
Copy the value that corresponds to the key “wc@2:core:0.3:keychain” and paste it into a text editor, and clean the JSON.

Copy the value that corresponds to the key that matches the topic. In our case, this key is “5ebab72e867494278a996f8ac7fd2102666387841808adcab26d97ce6a5c4f6e”, and the value is our symmetric key:
db215ebe9c641fd54ec1671be05680c3e28658aebf8555d82bfbde950af53ad4
Decrypting the message
We can use the same code WalletConnect uses to decrypt the message. Let’s take the decode function from the WalletConnect crypto package here and adapt it into a simplified JavaScript program:

Paste the symmetric key and the encoded message and then run the script. The decoded payload will be printed to the console. Using the irn_publish message from earlier, we get this:

We can see that the dApp sent a wc_sessionPropose message with optional namespaces pertaining to Solana.
We can also decode incoming messages that were sent by our wallet. These messages will have a red down arrow next to them in the dev console.
Notice that this message has a different topic from the previous message. After the initial session proposal is sent, a different topic will be used for subsequent messages. This is called the session topic.
We already retrieved the symmetric key for this topic from the keychain earlier: 9d95089650275a4beed805220fccc3fceb52565447b0dce776edaf4c31fda57b. So we can replace the symKey and message in the script with the new key and message, respectively, and run the script. The output is:

Now we know that Fireblocks responded with a wc_sessionSettle message, creating the session and accepting some, but not all, of the Solana chains. You can read more about these methods and other types of WalletConnect session events here.
We’ve now gone through how to monitor incoming and outgoing WalletConnect messages on a dApp and decode them using the symmetric key. This method allows us to take an investigation out of our own platform’s debug logs and have a wider view of the interaction. This method can be used by both wallet and dApp developers.
Happy debugging!