🛠️ API Documentation
Binance Chain Wallet injects a global API into websites visited by its users at window.BinanceChain
.
This API specification borrows heavily from API MetaMask provided, considering the massive adoption. So Web3 site developers can easily connect their dApps with the Binance Chain Wallet. The APIs allow websites to request users' Binance Smart Chain addresses, read data from the blockchain the user is connected to, and prompt the users to sign messages and transactions.
The presence of the provider object window.BinanceChain
indicates a Binance Chain/Binance Smart Chain user.
The API this extension wallet provides includes API specified by EIP-1193 and API defined by MetaMask (including some massively relied legacy ones).
Development Progress
Currently (version 1.112.8) as Binance Chain Wallet natively supports Binance Chain, we are planning to open a series of APIs for dApp developers to interact with Binance Chain. At the end of the day, most APIs available in Binance Chain javascript sdk would be available.
Currently, only the following is supported:
Difference with MetaMask
Please read through this section if you are a web3 developer who has integrated with MetaMask and interested in integrating with Binance Chain Wallet.
Inpage injected object
The biggest difference between Binance Chain Wallet and MetaMask is we inject BinanceChain
rather than ethereum
(or web3
) to the web page. So user could keep two extensions at the same time.
BinanceChain.request({method: "eth_sign", params: ["address", "message"])
We haven't supported the full complex signing data APIs MetaMask provided, while we only provide standard eth_sign
JSON-RPC call.
The message
item in params for this request on MetaMask has to be hex-encoded keccak256 hash (otherwise the API would silent failure for dapp https://www.reddit.com/r/Metamask/comments/9wp7kj/eth_sign_not_working/). In contrast, web3 developers could pass any message in plaintext to this method, and our UI would render it as it is to the wallet users.
BinanceChain.request({method: "eth_accounts"})
When this API is invoked without the user's approval, MetaMask would return an empty array.
In contrast, we would ask the user to unlock his wallet and return the address user connected to.
Upcoming Breaking Changes
Important Information
On November 16, 2020, MetaMask is making changes to their provider API that will be breaking for some web3 sites. These changes are upcoming, but you can prepare for them today. Follow this GitHub issue for updates.
In this implementation, some APIs will be supported as Legacy API (For example we will still implement the chainIdChanged
on BinanceChain object until MetaMask formally deprecates it).
Basic Usage
For any non-trivial Binance Smart Chain web application — a.k.a. web3 site — to work, you will have to:
Detect the Binance Smart Chain provider (
window.BinanceChain
)Detect which Binance Smart Chain network the user is connected to
Get the user's Binance Smart Chain account(s)
You can learn how to accomplish the 2
and 3
from above list by reviewing the snippet in the Using the Provider section.
The provider API is all you need to create a full-featured web3 application.
That said, many developers use a convenience library, such as ethers and web3.js, instead of using the provider directly. If you need higher-level abstractions than those provided by this API, we recommend that you use a convenience library.
Today, many dApps are built on top of the higher-level API provided by web3-react or use-wallet (which builds on top of web3-react).
web3-react
We made a tiny lib bsc-connector that implements the AbstractConnector interface of web3-react library. You can add this to your project in parallel with injected-connector by: yarn add @binance-chain/bsc-connector
or npm i @binance-chain/bsc-connector
.
use-wallet
There is an example in use-wallet origin repo shows how to 'inject' a customized web3-react connector to UseWalletProvider
:
Chain IDs
!!! warning
These are the IDs of the Binance Smart chains that Binance Chain Wallet supports by default.
Hex | Decimal | Network |
0x38 | 56 | Binance Smart Chain Main Network (bsc-mainnet) |
0x61 | 97 | Binance Smart Chain Test Network (bsc-testnet) |
This API can also return chain ids of Binance Chains if users switch to them. The possible return value would be:
Chain Id | Network |
Binance-Chain-Tigris | Binance Chain Main Network (bbc-mainnet) |
Binance-Chain-Ganges | Binance Chain Test Network (bbc-testnet) |
Properties
BinanceChain.chainId
The value of this property can change at any time, and should not be exclusively relied upon. See the chainChanged
event for details.
NOTE: See the Chain IDs section for important information about the Binance Chain Wallet provider's chain IDs.
A hexadecimal string representing the current chain ID.
BinanceChain.autoRefreshOnNetworkChange
As the consumer of this API, it is your responsibility to handle chain changes using the chainChanged
event. We recommend reloading the page on chainChange
unless you have a good reason not to.
Please refer to MetaMask Doc, the only difference is we injected a different object.
To disable this behavior, set this property to false
immediately after detecting the provider:
Methods
BinanceChain.isConnected()
Please refer to MetaMask Doc, the only difference is we injected a different object.
BinanceChain.request(args)
Please refer to MetaMask Doc, the only difference is we injected a different object.
We use this method to wrap an RPC API, Please see the Ethereum wiki.
Important methods from this API include:
Example
The code snippet below is as same as MetaMask's example, the only difference is we injected a different object.
BinanceChain.bnbSign(address: string, message: string): Promise<{publicKey: string, signature: string}>
We prepared an example for this API, please check out: https://github.com/binance-chain/js-eth-personal-sign-examples for more detail
Like eth_sign
enable dapp to verify a user has control over an ethereum address by signing an arbitrary message. We provide this method for dapp developers to request the signature of arbitrary messages for Binance Chain (BC) and Binance Smart Chain (BSC).
If address
parameter is a binance chain address (start with bnb
or tbnb
), we will simply calculate sha256 hash of the message and let user sign the hash with his binance chain address' private key. Note: Binance Chain uses the same elliptic curve (secp256k1
) as Ethereum.
If address
parameter is a binance smart chain address (start with 0x
), the message would be hashed in the same way with eth_sign
.
The returned publicKey
would be a compressed encoded format (a hex string encoded 33 bytes starting with "0x02", "0x03") for Binance Chain. And uncompressed encoded format (a hex string encoded 65 bytes starting with "0x04").
The returned signature
would be bytes encoded in hex string starting with 0x
. For BinanceChain, its r,s catenated 64 bytes in total. For Binance Smart Chain, like eth_sign
, its r, s catenated 64 bytes and a recover byte in the end.
DApp developers should verify whether the returned public key can be converted into the address user claimed in addition to an ECDSA signature verification. Because any plugin can inject the same object BinanceChain
as Binance Chain Wallet
As Binance Chain Wallet natively supports Binance Chain and Binance Smart Chain which are heterogeneous blockchains run in parallel. APIs would be different in any situation. (We would open APIs for Binance Chain very soon).
Developers could judge which network is selected by user currently via BinanceChain.chainId
or listening to the chainChanged
event via BinanceChain.on('chainChanged', callback)
.
To request for network switching, developers could invoke this API with bbc-mainnet
(Binance Chain Main Network), bsc-mainnet
(Binance Smart Chain Main Network), bbc-testnet
(Binance Chain Test Network), bsc-testnet
(Binance Smart Chain Test Network) to prompt user to agree on network switching.
BinanceChain.requestAccounts()
Request all accounts maintained by this extension.
The id
in response would be used as accountId
for the APIs for Binance Chain.
This method would return an array of Account:
For example:
BinanceChain.transfer({fromAddress:string, toAddress:string, asset:string, amount:number, memo?: string, sequence?: number, accountId:string, networkId:string})>
Transfer certain amount
of asset
(BNB or BEP2) on Binance Chain.
accountId
could be retrieved from the BinanceChain.requestAccounts
API (id
field of each account)
networkId
could be bbc-mainnet
or bbc-testnet
For example:
This will ask the user's approval for transferring 1 BNB to himself.
BinanceChain.transfer({fromAddress:"tbnb1sndxdzsg42jg8lc0hehx8dzzpyfxrvq937mt0w", toAddress:"tbnb1sndxdzsg42jg8lc0hehx8dzzpyfxrvq937mt0w", asset:"BNB", amount:1, accountId:"fba0b0ce46c7f79cd7cd91cdd732b6c699440acf8c539d7e7d753d38c9deea544230e51899d5d9841b8698b74a3c77b79e70d686c76cb35dca9cac0e615628ed", networkId:"bbc-testnet"})
This will ask the user's approval for transferring 1 BUSD to himself.
BinanceChain.transfer({fromAddress:"tbnb1sndxdzsg42jg8lc0hehx8dzzpyfxrvq937mt0w", toAddress:"tbnb1sndxdzsg42jg8lc0hehx8dzzpyfxrvq937mt0w", asset:"BUSD-BAF", amount:1, accountId:"fba0b0ce46c7f79cd7cd91cdd732b6c699440acf8c539d7e7d753d38c9deea544230e51899d5d9841b8698b74a3c77b79e70d686c76cb35dca9cac0e615628ed", networkId:"bbc-testnet"})
Events
Please refer to MetaMask Doc, the only difference is we injected a different object.
connect
Please refer to MetaMask Doc, the only difference is we injected a different object.
disconnect
Please refer to MetaMask Doc, the only difference is we injected a different object.
accountsChanged
Please refer to MetaMask Doc, the only difference is we injected a different object.
chainChanged
Please refer to MetaMask Doc, the only difference is we injected a different object.
message
Please refer to MetaMask Doc, the only difference is we injected a different object.
Errors
Please refer to MetaMask Doc, the only difference is we injected a different object.
Using the Provider
This snippet explains how to accomplish the three most common requirements for web3 sites:
Detect which BinanceChain network the user is connected to
Get the user's BinanceChain account(s)
Legacy API
!!! warning You should never rely on any of these methods, properties, or events in practice.
This section documents MetaMask's legacy provider API.
To be compatible with existing dApps that support MetaMask, Binance Chain Wallet implements them as well, but please don't rely on them. We may deprecate them soon in the future.
Legacy Properties
BinanceChain.networkVersion (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
BinanceChain.selectedAddress (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
Legacy Methods
BinanceChain.enable() (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
BinanceChain.sendAsync() (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
BinanceChain.send() (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
This method behaves unpredictably and should be avoided at all costs. It is essentially an overloaded version of BinanceChain.sendAsync()
.
BinanceChain.send()
can be called in three different ways:
You can think of these signatures as follows:
This signature is exactly like
BinanceChain.sendAsync()
This signature is like an async
BinanceChain.sendAsync()
withmethod
andparams
as arguments, instead of a JSON-RPC payload and callbackThis signature enables you to call the following RPC methods synchronously:
eth_accounts
eth_coinbase
eth_uninstallFilter
net_version
Legacy Events
close (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
chainIdChanged (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
networkChanged (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
notification (DEPRECATED)
Please refer to MetaMask Doc, the only difference is we injected a different object.
Last updated