BDB 主网签名接口说明

面向在 BDB Chain 主网 上对接 BDBKEY 内置 DApp 浏览器的 Web 应用。 签名能力通过浏览器内注入的 EIP-1193 Provider(window.ethereum)提供,与链上 JSON-RPC 的「签名 HTTP 接口」无关。

文档版本 对应 App 1.5.4(versionCode 154) · 公链 RPC / 转账总览

1. 适用范围与结论

DApp 只需按 Ethereum 生态标准实现 EIP-1193;无需针对 BDB 单独定义新的签名协议名或字段。

2. BDB 主网参数(签名上下文)

项值
Chain ID(十进制)20240606
Chain ID(十六进制)0x134d8de
原生币BDB,18 位小数
默认 RPChttps://chain.bdbweb3.us
区块浏览器https://scan.bdbweb3.us

交易与 typed data 中的 chainId 须与上表一致(EIP-155 / EIP-712 防重放)。 若 DApp 请求的链与钱包当前网络不一致,App 会提示切换网络或拒绝签名。

3. Provider 对象

页面加载后注入:

连接示例(Ethers v6)

const provider = new ethers.BrowserProvider(window.ethereum);
const accounts = await provider.send("eth_requestAccounts", []);
const signer = await provider.getSigner();
const address = await signer.getAddress();
const network = await provider.getNetwork();
// network.chainId === 20240606n

切换到 BDB 主网

await window.ethereum.request({
  method: "wallet_switchEthereumChain",
  params: [{ chainId: "0x134d8de" }]
});
// 若返回 4902(链未添加),再 wallet_addEthereumChain,参数见 bdb-chain-integration.html

4. ethereum.request 方法一览

methodparams 要点成功 result用户确认
eth_requestAccounts [] ["0x…"] 当前钱包地址 否(已绑定当前钱包)
eth_accounts [] 已连接时 ["0x…"],否则 [] 否
eth_chainId [] "0x134d8de"(随当前网络变化) 否
personal_sign [message, address] 或 [address, message](钱包会自动识别哪一项是 20 字节地址) "0x…" 65 字节签名 hex 是(ActionSheet + 可选密码)
eth_sign [address, messageHex] 签名 hex 是
eth_signTypedData
eth_signTypedData_v3
eth_signTypedData_v4
[address, typedDataJson] 顺序可互换;typedDataJson 可为对象或 JSON 字符串 签名 hex(EIP-712) 是
eth_sendTransaction [txObject] 见下文 交易哈希 "0x…"(签名后由钱包广播) 是(ActionSheet 交易确认 + Gas)
eth_call 标准 [{ to, data, value?, gas? }] 返回 data hex 否
wallet_switchEthereumChain [{ chainId: "0x…" }] null 跨主网时可能弹窗确认
wallet_addEthereumChain 标准 add chain 对象 null 未知链时弹窗
wallet_requestPermissions
wallet_getPermissions
兼容 MetaMask 含 eth_accounts 的 permissions 数组 否

经钱包代理的 JSON-RPC(只读 / 估算)

以下方法不弹签名窗,由 App 转发到当前 DApp 上下文链的 RPC:

eth_blockNumber、eth_getBalance、eth_getTransactionCount、 eth_gasPrice、eth_estimateGas、eth_getCode、 eth_getStorageAt、eth_maxPriorityFeePerGas、eth_feeHistory、 eth_getBlockByNumber、eth_getBlockByHash

未列出的 method:若存在旧版 sendAsync 实现则继续走原路径;否则 request 可能 reject「Provider does not support request」。

5. 消息签名

5.1 personal_sign(EIP-191,登录 / SIWE 常用)

const message = "Login to My DApp at " + Date.now();
const sig = await window.ethereum.request({
  method: "personal_sign",
  params: [message, userAddress]
});
// sig: 0x + r + s + v

服务端验签时使用与 Ethereum 相同的 personal_sign 规则(前缀 \x19Ethereum Signed Message:\n + 长度 + 消息体)。

5.2 EIP-712(eth_signTypedData_v4)

const typedData = {
  types: { EIP712Domain: [...], Mail: [...] },
  primaryType: "Mail",
  domain: { name: "...", version: "1", chainId: 20240606, verifyingContract: "0x..." },
  message: { ... }
};
const sig = await window.ethereum.request({
  method: "eth_signTypedData_v4",
  params: [userAddress, typedData]
});

domain.chainId 必须与 BDB 主网 20240606 一致,且与钱包当前网络匹配,否则 App 拒绝并提示网络不兼容。

5.3 用户界面流程

  1. DApp 调用签名方法 → 底部 ActionSheetSignDialog 展示请求来源域名、消息摘要、签名地址。
  2. 用户确认 → 若钱包启用密码/生物识别,则 AppPasswordPrompt 验证后本地签名。
  3. 成功 → Promise resolve 为 0x 前缀签名;失败或关闭 → reject(见「取消与错误」)。
登录类 DApp 在 personal_sign 期间会进入短暂「签名宽限期」,避免 WebView 重载导致回调丢失;DApp 侧仍应使用标准 await provider.request,不要依赖页面刷新。

6. 交易签名与发送(eth_sendTransaction)

6.1 请求体字段

params[0] 支持 Ethereum 常见字段(hex 或 number,钱包会 normalize):

字段说明
from可选;实际发送账户为 App 当前钱包
to收款或合约地址
value原生 BDB 数量(wei,hex)
data / input合约 calldata
gas / gasLimit可选;未填时 App 估算
gasPriceBDB 主网推荐使用 legacy 字段
maxFeePerGas / maxPriorityFeePerGas非 BDB 链或 DApp 显式指定 EIP-1559 时使用;BDB 确认页优先 legacy
nonce可选;未填时 RPC 查询
chainId建议 0x134d8de;与当前网络不一致时触发切链或拒绝

6.2 行为说明

6.3 Ethers 示例

const tx = await signer.sendTransaction({
  to: "0xRecipient",
  value: ethers.parseEther("1.0"),
  chainId: 20240606
});
const receipt = await tx.wait();

7. BDB 主网 Gas 与手续费展示

DApp 自行构造交易时,可调用代理 RPC 的 eth_gasPrice、eth_estimateGas,或让钱包在确认页覆盖/补全 Gas 参数。

8. 取消与错误

场景DApp 侧表现
用户在签名/交易 ActionSheet 点取消或下滑关闭 Promise reject,错误消息常为字符串 "cancelled"(Error: cancelled)
密码验证失败 reject(如 auth failed / cancelled,以实现为准)
EIP-712 解析失败 不展示签名页,直接 cancel 回调
请求链 ID 不支持或与当前网络不兼容 弹错误对话框后 cancel
交易 JSON 无效 reject,带具体解析错误信息
try {
  await window.ethereum.request({ method: "personal_sign", params: [msg, addr] });
} catch (e) {
  if (e.message === "cancelled") {
    // 用户拒绝
  }
}

建议在 UI 上将 cancelled 映射为用户可理解的「已取消签名」,勿当作链或 RPC 故障。

9. Provider 事件

事件payload说明
connect{ chainId: "0x134d8de" }账户通知时附带触发
accountsChanged["0x…"]App 内切换钱包后更新;为避免部分 DApp 误 logout,不会在仍绑定钱包时 emit 空数组
chainChanged新 chainId hex用户切换网络或 wallet_switchEthereumChain 成功后;DApp 应 reload 或重建 provider 状态
window.ethereum.on("chainChanged", (chainId) => {
  console.log("chainChanged", chainId);
});
window.ethereum.on("accountsChanged", (accounts) => {
  console.log("accountsChanged", accounts);
});

10. WebView JavaScript 对话框

页面中的 alert、confirm、prompt 由 Web3JsDialogHelper 渲染为 App 风格弹窗(非系统 WebView 默认框)。

与链上签名无关,但登录流程中若有 JS 对话框,行为与桌面浏览器「取消 = false / null」一致。

11. WalletConnect(可选)

通过 WalletConnect 连接时,支持的签名/交易 method 与上表一致,包括:

eth_sendTransaction、eth_signTransaction、 personal_sign、eth_sign、 eth_signTypedData / _v3 / _v4、 wallet_switchEthereumChain

用户在手机 App 上同样通过 ActionSheet 确认;拒绝时 WC 层返回「User rejected request」类错误。

12. Api V1 深链(系统浏览器,非 WebView Provider)

若从外部浏览器打开符合 AlphaWallet Api V1 规范的 HTTPS 链接,可唤起 BDBKEY 做有限操作(与 BDB 链无专用 path,但可在 redirect 回 DApp 后继续走主网逻辑)。

Path用途
/wallet/v1/connect连接并回跳地址
/wallet/v1/signpersonalmessage请求 personal_sign 类签名

签名请求 query 参数(节选):

成功回跳时在 redirecturl 上追加 call=signpersonalmessage 与 signature=0x…。

主网 DApp 优先在 App 内置浏览器使用 window.ethereum;Api V1 适用于外部 H5 唤起钱包的兼容场景。

13. 实现参考(维护者)

模块路径
EIP-1193 注入脚本app/src/main/res/raw/init.js
JavaScript 桥app/.../web3/SignCallbackJSInterface.java
DApp 签名/交易 UIDappBrowserFragment.java、ActionSheetSignDialog.java、ActionSheetDialog.java
回调成功/取消Web3View.java(executeCallback / cancelled)
BDB 网络与 RPClib/.../EthereumNetworkBase.java、BdbDexConfig.java

公链 JSON-RPC、代币地址、DEX 合约见 BDB Chain 公链接口对接说明。