Auroran Bridge 充提对接指南
本文档说明如何通过 EVM 侧 Auroran Bridge 合约 与 Auroran Chain API 完成跨链充提对接。合约 ABI 见 合约接口参考,链上 Action 见 Chain API — Bridge 充提。
1. 架构概览
Auroran Bridge 是部署在 EVM 链(如 BSC)上的充提桥接合约。合约不托管资金:
- 充值:用户调用
deposit,代币从用户钱包直接转入projectAddress;合约仅记录账本并发出事件。 - 提款:结算操作员调用
settleWithdraw,代币从操作员钱包转入用户收款地址;合约记录放款并发出事件。
链下程序监听 EVM 事件,并通过 Chain API 与 Auroran 链账本同步。
1.1 角色分工
| 角色 | 职责 |
|---|---|
| 用户 | EVM 侧 approve + deposit;Auroran 链侧 EIP-712 签名 WithdrawRequest |
| 结算操作员(SettlementOperator) | 监听 EVM / Auroran 链事件,调用 Chain API RecordDeposit / CreditDeposit / WithdrawSettle;EVM 侧 approve + settleWithdraw 放款 |
| 合约 Owner | 管理 projectAddress、暂停开关、blockConfirmations 等 |
| Operator | 仅可调用 pauseDeposits 紧急暂停充值 |
1.2 关键标识映射
EVM 合约与 Auroran 链 Bridge API 通过以下字段对齐:
| EVM(Auroran Bridge) | Auroran 链(Chain API) | 说明 |
|---|---|---|
chainTag(如 "bsc") | external_ref.chain | 外部链标识,小写 |
deposit() 返回的 seq | external_ref.seq | 充值去重键,1-based |
DepositRecorded 事件 | RecordDeposit 参数 | 链下据此构造登记请求 |
WithdrawSettled 事件的 zeptoRequestId | WithdrawSettle.request_id | 提款请求 ID(合约字段名 zeptoRequestId) |
代币 decimals() | amount SCALE_6 换算 | 见 §4 金额换算 |
用户交互地址为 TransparentUpgradeableProxy 地址(非 implementation)。部署说明见合约仓库
scripts/deploy-bridge.sh。
2. 接入准备
2.1 所需信息
| 项 | 获取方式 |
|---|---|
| Bridge Proxy 地址 | 部署输出 / 运维配置 |
| 桥接 ERC20 地址 | bridge.token() 或 bridgeChainInfo().tokenAddr |
chainTag | bridge.chainTag()(须与 WithdrawRequest.chain 一致) |
blockConfirmations | bridge.blockConfirmations() 或 bridgeChainInfo().confirmations |
| Chain API 端点 | {node}/api/v1/query · {node}/api/v1/action — 见 Chain API |
| SettlementOperator 凭证 | 持 SettlementOperator 角色的 Agent 或 Master — 见 签名与鉴权 |
2.2 ABI 下载
合约 ABI:
/abi/AuroranBridge.abi.json
完整 URL:https://docs.auroran.io/abi/AuroranBridge.abi.json
2.3 推荐依赖
| 语言 | 库 |
|---|---|
| TypeScript | viem 或 ethers v6 |
| Go | go-ethereum bind |
| Rust | alloy |
下文示例使用 viem。
3. 充值流程
3.1 用户侧(EVM)
- 读取
token()获取 ERC20 地址。 - 对 Bridge Proxy 地址执行
token.approve(bridge, amount)。 - 调用
deposit(amount),获得返回值seq。 - 等待交易确认;可从
DepositRecorded事件校验seq、owner、amount。
import { createPublicClient, createWalletClient, http, parseUnits } from 'viem';
import { bsc } from 'viem/chains';
import bridgeAbi from './AuroranBridge.abi.json';
const BRIDGE = '0x...' as const; // Proxy 地址
const amount = parseUnits('100', 18); // 按 token.decimals() 换算
const wallet = createWalletClient({ chain: bsc, transport: http(), account });
const publicClient = createPublicClient({ chain: bsc, transport: http() });
// 1. approve
await wallet.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'approve',
args: [BRIDGE, amount],
});
// 2. deposit
const hash = await wallet.writeContract({
address: BRIDGE,
abi: bridgeAbi,
functionName: 'deposit',
args: [amount],
});
const receipt = await publicClient.waitForTransactionReceipt({ hash });
// 从 receipt.logs 解析 DepositRecorded,或调用 depositCount() / getDeposit(seq)
注意:
amount为代币原生精度(如 XUSDT 为 18 位)。depositsPaused == true时deposit会 revertDepositsPausedError。- 代币直达
projectAddress,Bridge 合约余额始终为 0。
3.2 结算侧(链下 → Auroran 链)
结算服务监听 DepositRecorded,在达到 blockConfirmations 后向 Chain API 提交两笔 Action:
Step 1 — RecordDeposit
signer 须持 SettlementOperator 角色。参数见 write-actions §11.1。
| 字段 | 来源 |
|---|---|
external_ref.chain | bridge.chainTag() |
external_ref.seq | DepositRecorded.seq |
tx_hash | 充值交易的 32 字节 hash(JSON 字节数组) |
account | DepositRecorded.owner |
amount | 按 §4 转为 SCALE_6 字符串 |
bsc_block | DepositRecorded.blockNumber |
bsc_ts | DepositRecorded.timestamp |
提交前可用 getBridgeDepositByExternalRef 检查是否已登记,避免重复:
{ "method": "getBridgeDepositByExternalRef", "params": { "chain": "bsc", "seq": 50001 } }
Step 2 — CreditDeposit
RecordDeposit 成功后,用返回的 Auroran 侧 seq 调用 CreditDeposit:
{ "method": "CreditDeposit", "params": { "seq": 101 } }
3.3 充值状态机
| 阶段 | EVM | Auroran 链 |
|---|---|---|
| 用户已转账 | DepositRecorded 已发出 | — |
| 已登记 | — | status: "Recorded" |
| 已入账 | — | status: "Credited",用户余额增加 |
4. 金额换算
| 侧 | 格式 | 示例 |
|---|---|---|
EVM deposit / settleWithdraw | uint256,代币 decimals() | 100000000000000000000(18 位 = 100 代币) |
Chain API amount | SCALE_6 decimal string | "100.000000" |
换算公式(tokenDecimals 来自 bridgeChainInfo().tokenDecimals):
auroran_amount = evm_amount / 10^tokenDecimals → 格式化为 6 位小数的 canonical string
evm_amount = parseUnits(auroran_amount, tokenDecimals)
若 tokenDecimals == 6,数值一一对应;若为 18,须除以 10^12。
5. 提款流程
5.1 用户侧(Auroran 链)
用户通过钱包 EIP-712 签名提交 WithdrawRequest(User-Signed 通道)。chain 字段须与 Bridge 的 chainTag 一致(如 "bsc")。
详见 write-actions §11.3 与 write-actions §3.2(EIP-712 typed data)。
5.2 结算侧(Auroran 链 → EVM → Auroran 链)
Step 1 — 监听提现请求
通过 Chain API WebSocket bridge 主题或轮询 listBridgeWithdrawals(status: "pending")获取待处理提款。
Step 2 — EVM 放款
- 确认
isZeptoRequestIdUsed(requestId) == false。 - 操作员钱包
approve(bridge, amount)。 - 调用
settleWithdraw(zeptoRequestId, amount, recipient):zeptoRequestId= Auroran 链request_idamount= 按 §4 转为 EVM 原生精度recipient= 用户指定的 EVM 收款地址(与WithdrawRequest.owner对应)
const requestId = 2001n;
const amount = parseUnits('500', 18);
const recipient = '0x1111...0000' as const;
await wallet.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: 'approve',
args: [BRIDGE, amount],
});
await wallet.writeContract({
address: BRIDGE,
abi: bridgeAbi,
functionName: 'settleWithdraw',
args: [requestId, amount, recipient],
});
注意:
- 无链上权限限制——谁付款谁调用;代币从
msg.sender转出。 zeptoRequestId为去重键,重复调用 revertZeptoRequestIdAlreadyUsed。withdrawalsPaused == true时 revertWithdrawalsPausedError。
Step 3 — WithdrawSettle
EVM 交易确认后,向 Chain API 提交 WithdrawSettle:
| 字段 | 来源 |
|---|---|
request_id | Auroran 链提现请求 ID |
external_tx.tx_hash | settleWithdraw 交易的 32 字节 hash |
external_tx.bsc_block | 放款区块号 |
external_tx.bsc_ts | 放款区块时间戳(秒) |
5.3 提款状态机
| 阶段 | Auroran 链 | EVM |
|---|---|---|
| 用户发起 | status: "Pending" | — |
| EVM 已放款 | — | WithdrawSettled 已发出 |
| 结算完成 | status: "Settled" | isZeptoRequestIdUsed == true |
若 EVM 放款失败,可调用 WithdrawRefund 将资金退回用户 Auroran 链余额。
6. 事件监听
结算服务须订阅以下 EVM 事件(完整字段见 合约接口 — 事件):
| 事件 | 监听方 | 用途 |
|---|---|---|
DepositRecorded | 充值结算 | 触发 RecordDeposit |
WithdrawSettled | 提款对账 | 确认 EVM 放款,触发 WithdrawSettle |
DepositsPaused / DepositsUnpaused | 运维 | 暂停/恢复充值入口 |
WithdrawalsPaused / WithdrawalsUnpaused | 运维 | 暂停/恢复提款结算 |
6.1 DepositRecorded 过滤示例(viem)
const logs = await publicClient.getLogs({
address: BRIDGE,
event: {
type: 'event',
name: 'DepositRecorded',
inputs: [
{ name: 'seq', type: 'uint64', indexed: true },
{ name: 'owner', type: 'address', indexed: true },
{ name: 'amount', type: 'uint256', indexed: false },
{ name: 'blockNumber', type: 'uint64', indexed: false },
{ name: 'timestamp', type: 'uint64', indexed: false },
],
},
fromBlock: lastProcessedBlock,
});
6.2 断点续传
- 充值:以
depositCount()或最大已处理seq为游标;漏扫时按seq调用getDeposit(seq)补全。 - 提款:以
isZeptoRequestIdUsed+listBridgeWithdrawals交叉校验。
7. 对账与查询
| 需求 | EVM | Auroran 链 |
|---|---|---|
| 单笔充值 | getDeposit(seq) | getBridgeDeposit / getBridgeDepositByExternalRef |
| 充值列表 | getDeposits(offset, limit) | listBridgeDeposits |
| 单笔提款 | getWithdraw(withdrawId) | getBridgeWithdrawal |
| 提款列表 | getWithdrawals(offset, limit) | listBridgeWithdrawals |
| 去重检查 | isZeptoRequestIdUsed(requestId) | getBridgeDepositByExternalRef |
| 全局闸门 | depositsPaused / withdrawalsPaused | getBridgeSettlement |
历史对账可结合 历史与审计 — bridge-flows。
8. 错误处理
8.1 EVM revert
| 错误 | 场景 | 处理建议 |
|---|---|---|
DepositsPausedError | 充值已暂停 | 通知用户,等待 DepositsUnpaused |
WithdrawalsPausedError | 提款已暂停 | 暂停 EVM 放款,等待恢复 |
ZeptoRequestIdAlreadyUsed | 重复结算 | 查 getWithdraw 确认已放款,补发 WithdrawSettle |
TransferAmountMismatch | 代币转账异常(fee-on-transfer 等) | 检查代币合约兼容性 |
ZeroAmount | 金额为 0 | 校验换算逻辑 |
完整列表见 合约接口 — 错误。
8.2 Auroran 链拒绝
| 场景 | 处理 |
|---|---|
external_ref 重复 | 已登记,跳过 RecordDeposit,检查是否需 CreditDeposit |
settlement_paused | 调用 getBridgeSettlement,等待 Admin 恢复 |
WithdrawAvailableInsufficient | 用户余额不足,拒绝或等待 |
9. 安全检查清单
- 使用 Proxy 地址 而非 implementation 地址
-
chainTag与WithdrawRequest.chain、RecordDeposit.external_ref.chain一致 - 充值监听等待
blockConfirmations后再提交RecordDeposit -
RecordDeposit前先查getBridgeDepositByExternalRef防重 -
settleWithdraw前查isZeptoRequestIdUsed防重 - 金额换算使用
bridgeChainInfo().tokenDecimals,勿硬编码 - SettlementOperator 私钥安全存储,建议使用 Agent 委托
- 监控
depositsPaused/withdrawalsPaused/settlement_paused
10. 相关文档
| 文档 | 内容 |
|---|---|
| 合约接口参考 | 全部函数、事件、错误、数据结构 |
| Chain API — Bridge 写操作 | RecordDeposit / CreditDeposit / WithdrawSettle |
| Chain API — Bridge 读方法 | getBridgeDeposit / listBridgeWithdrawals 等 |
| Chain API — 事件 | Auroran 链 Bridge 事件域 |
| 签名与鉴权 | SettlementOperator Agent 配置 |