The Binance Chain Web Wallet supports connecting with external wallet providers via the WalletConnect protocol.
WalletConnect allows the user to scan a QR code from the wallet app to unlock and use their wallet seamlessly in the web UI.
In order for this to work, some modifications to the standard WalletConnect protocol are used in the Binance Chain wallet's implementation.
See the list of wallets which support WalletConnect on Binance Chain here
Wallet providers should make use of the WalletConnect Client SDK for their target programming language and OS. There are implementations on GitHub for iOS, Android, React Native, etc.
Since we do not use Ethereum transactions, there are some differences:
-
Typically
sendTransaction
is used with Ethereum transaction parameters in WalletConnect dApp integrations. But in Binance Chain's case, instead of invokingsendTransaction
in the WalletConnect flow, the newsendCustomRequest
call is used instead with a method calledbnb_sign
(see below). -
The external wallet provider is responsible for sending back the signature and public key of the transaction but should not broadcast the transaction itself. We have instead defined a custom
result
format in the form of stringified JSON containing the signature and public key. The reason for this is that the wallet app probably does not have access to the complete serialized binary form of the transaction (as this requires Amino encoding). -
The web wallet will send back a second custom call (after
bnb_sign
) calledbnb_tx_confirmation
, which contains the boolean result of the transaction build/broadcast and any error message encountered by the web wallet during broadcasting. In a complete implementation, this confirmation callback should be responded to with a call toapproveRequest
.
This sequence diagram shows the flow of messages when the web wallet interacts with an external wallet provider via WalletConnect.
A custom call request adheres to this structure:
{
"id": 1,
"jsonrpc": "2.0",
"method": "method_name",
"params": [{ ... }],
}
We have two custom call request formats, here are examples of them:
{
"method": "bnb_sign",
"params": [
{
"account_number": "34",
"chain_id": "Binance-Chain-Nile",
"data": null,
"memo": "test",
"msgs": [
{
"inputs": [
{
"address": "tbnb1hgm0p7khfk85zpz5v0j8wnej3a90w709zzlffd",
"coins": [
{
"amount": 1000000000,
"denom": "BNB",
},
],
},
],
"outputs": [
{
"address": "tbnb1ss57e8sa7xnwq030k2ctr775uac9gjzglqhvpy",
"coins": [
{
"amount": 1000000000,
"denom": "BNB",
},
],
},
],
},
],
"sequence": "31",
"source": "1",
}
]
}
A response like this should be sent back from the wallet app:
{
"id": 1553682007906047,
"result": "{\"signature\":\"...\",\"publicKey\":\"...\"}"
}
In result
, a JSON-encoded object must be included containing the following hex-string properties: signature
, publicKey
.
Note that:
-
id
andjsonrpc
are usually pre-filled by the client SDK, so there should be no need to set this in the object yourself. -
signature
should be 64 bytes in length (128 hex chars) -
publicKey
should be 65 bytes in length (130 hex chars, non-compressed form, prefixed with0x04
)
{
"method": "bnb_tx_confirmation",
"params": [
{
"ok": true,
"error": "Error message (optional)"
}
]
}
Receipt of the bnb_tx_confirmation
should be confirmed by the app with approveRequest
as per the WalletConnect protocol flow.
For this response, result
may be empty or contain an empty JSON-encoded object:
A response like this should be sent back from the wallet app:
{
"id": 1553682007906050,
"result": ""
}
Remember to call killSession()
when the user has finished using the integration from your app!
This will redirect the user back to the unlock screen in the web wallet.