Documentation Index
Fetch the complete documentation index at: https://developer.bron.org/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Broadcasters (also called Integrators) — partners that create user orders on-chain on behalf of their users, wallets, or marketplaces.
They broadcast user intents into the Bron network and receive a front-end fee per executed order.
Each broadcaster must be registered in the BroadcasterRegister smart contract and approved by the Bron DAO before creating any orders.
Registration
Registration is a two-step process: the broadcaster funds a BRON deposit and submits a request, then the DAO accepts it.
1. Submit a registration request
BroadcasterRegister.registerBroadcaster(uint256 _amountOfBronTokens)
Before calling, approve the BRON token allowance for BroadcasterRegister:
bronToken.approve(broadcasterRegisterAddress, _amountOfBronTokens)
After the call, the broadcaster status becomes PENDING. BRON tokens are locked in the contract; if the DAO rejects the request, they are returned automatically. The broadcaster can also call cancelBroadcasterRegistration() while still in PENDING to back out and reclaim the deposit.
2. DAO approval
The Bron DAO reviews the request and calls registerBroadcasterResponse(broadcaster, isAccepted). On acceptance, status becomes ACTIVE and createOrder calls become possible. Until that point, createOrder reverts with BR_INVALID_STATUS.
3. Manage the BRON balance
Every createOrder deducts a fixed amount of BRON (bronTokenOrderCreationCost) from the broadcaster balance. Top-up and withdrawal:
topUpBroadcaster(uint256) — add more BRON to your balance.
requestWithdrawBroadcasterAmount(uint256) → wait withdrawalDelay → claimWithdrawBroadcasterAmount() — withdraw with a cooldown.
cancelWithdrawalRequest() — cancel a pending withdrawal.
If the BRON balance falls below bronTokenOrderCreationCost, the next createOrder reverts with BR_INVALID_PARAMS.
Order creation
Function
function createOrder(
CreateOrderParams memory _create,
string memory _userSettlementFromAddress,
uint256 _frontEndFee
) external returns (string memory);
CreateOrderParams
| Field | Description |
|---|
orderId | Unique string ID (UUID-style). Idempotency key — must not exist on-chain |
baseNetworkId | Network where user sends tokens (see Reference for network IDs) |
baseTokenAddress | Token contract on base chain, or "0x" for native assets |
baseAmount | Amount user sends (in token decimals). Set 0 if quoteAmount is fixed instead |
quoteNetworkId | Network where user receives tokens |
quoteTokenAddress | Token contract on quote chain, or "0x" for native assets |
quoteAmount | Amount user receives. Set 0 if baseAmount is fixed instead |
maxPrice_e18 | Slippage limit, scaled by 1e18 (note: enforced as min acceptable price internally) |
orderValueInUSD_e18 | Total value of order in USD, scaled by 1e18 |
auctionDuration | Solver auction duration in seconds |
userAddress | User’s destination address on quote network |
liquidationReceiver | Deprecated — always pass address(0) |
Other parameters
| Param | Description |
|---|
_userSettlementFromAddress | Required. Address from which the user will send funds on the base network. The contract binds this address to your broadcaster — another broadcaster cannot reuse it while your order is active |
_frontEndFee | Broadcaster fee, encoded as percent × 10000 (i.e. 1 unit = 0.0001%). Examples: 100 = 0.01% (1 bps), 300 = 0.03% (3 bps), 10000 = 1%. Must be <= 100000 (10%, the protocol cap). The fee amount is computed as orderAmount × _frontEndFee / 1_000_000 |
Example
const tx = await orderEngine.createOrder(
{
orderId: 'ord_01H7FZ9A8XY...',
baseNetworkId: 'BTC',
baseTokenAddress: '0x',
baseAmount: Big(0.01).mul(Big(10).pow(8)).toFixed(), // 0.01 BTC
quoteNetworkId: 'ETH',
quoteTokenAddress: '0x',
quoteAmount: 0, // user fixes baseAmount, quote is the auction outcome
maxPrice_e18: Big(27.96).mul(Big(0.994)).mul(Big(10).pow(18)).toFixed(),
orderValueInUSD_e18: Big(1220).mul(Big(10).pow(18)).toFixed(),
auctionDuration: 20,
userAddress: '0x1234...',
liquidationReceiver: '0x0000000000000000000000000000000000000000', // deprecated
},
'bc1q...userSettlementFromAddress...', // _userSettlementFromAddress
300, // _frontEndFee = 0.03% (3 bps)
{ gasLimit: 1_000_000 }
);
await tx.wait();
Order lifecycle
Subscribe to OrderStatusChanged(string orderId, OrderStatus status) from OrderEngine. The full status enum and what the broadcaster should do at each step:
| Status code | Status name | What broadcaster does |
|---|
| 0 | NOT_EXIST | Order has not been created yet |
| 1 | USER_INITIATED | Order created, auction has not started — wait for solver reactions |
| 2 | AUCTION_IN_PROGRESS | A solver has reacted with a quote. Once createdAt + auctionDuration has passed, the auction is effectively over: send user funds from _userSettlementFromAddress to the solver address on baseNetworkId, then call setUserTxOnBaseNetwork(orderId, txHash) |
| 4 | WAIT_FOR_ORACLE_CONFIRM_USER_TX | Oracles are verifying the user transaction. No action required |
| 5 | WAIT_FOR_SOLVER_TX | Oracles confirmed user tx. Solver is sending funds on the quote network |
| 6 | WAIT_FOR_ORACLE_CONFIRM_SOLVER_TX | Oracles are verifying the solver transaction. No action required |
| 7 | COMPLETED | Done. Front-end fee is credited and can be claimed via collectBroadcasterFees |
| 8 | LIQUIDATED | Solver failed to deliver. Order will be reassigned to a backup solver |
| 9 | CANCELLED | Order cancelled (by broadcaster or due to user-side timeout) |
| 10 | TO_BE_LIQUIDATED | Intermediate state during liquidation reassignment |
| 11 | DECIDE_BY_DAO | Edge case (e.g. all oracles offline) — DAO arbitration required |
Status code 3 (WAIT_FOR_USER_TX) is not emitted as an OrderStatusChanged event. It only appears as a derived value when reading orders via Metadata.getOrderFullResponse(orderId) once the auction has timed out but the user-settlement window is still open. After setUserTxOnBaseNetwork, the order moves directly from AUCTION_IN_PROGRESS to WAIT_FOR_ORACLE_CONFIRM_USER_TX.
The broadcaster’s only required on-chain action after order creation is sending user funds and calling setUserTxOnBaseNetwork. Everything else is driven by the solver and oracles.
Cancellation
The broadcaster can cancel an order by calling:
OrderEngine.cancelOrder(string memory _orderId)
Cancellation is allowed only in:
USER_INITIATED — auction has not started or no solver has reacted yet.
AUCTION_IN_PROGRESS — provided the user-settlement window (auctionDuration + userSettlementTime) has not yet expired.
Once the order moves to WAIT_FOR_USER_TX or later, on-chain cancellation is not available — the order will either complete or expire via timeouts handled by oracles.
Idempotency and retries
orderId is the idempotency key. The contract reverts with BC_INVALID_PARAMS if an order with the same id already exists.
- Generate
orderId deterministically on your side before sending the transaction, so a tx that gets dropped, replaced, or reorged can be safely retried with the same id.
- After submitting
createOrder, watch for OrderStatusChanged(orderId, USER_INITIATED). If it doesn’t arrive within a reasonable confirmation window, query OrderEngine.getOrder(orderId) — if status == NOT_EXIST, the tx didn’t land and you can resubmit with the same orderId.
- The same logic applies to
setUserTxOnBaseNetwork: the _userTxHash is also tracked for uniqueness — BC_INVALID_PARAMS is raised if a tx hash is reused.
Front-end fee
You set _frontEndFee per order in createOrder (units of 1/100000, max 100000). After an order completes, the fee is automatically credited to your balance and can be withdrawn at any time:
SolverRegister.collectBroadcasterFees(address tokenAddress, address receiver, uint256 amount)
The fee is paid in the same token the solver settled in (i.e. the quote token). Fees from different orders / different tokens accumulate independently.
Errors
| Error | Meaning |
|---|
BR_INVALID_STATUS() | Broadcaster is not ACTIVE (still PENDING, SUSPENDED, or INACTIVE) |
BR_INVALID_PARAMS() | Invalid registration / top-up / withdraw params, or insufficient BRON |
BC_INVALID_PARAMS() | Invalid order params, duplicate orderId, or reused userTxHash |
BC_INVALID_CALLER() | Caller does not match the role expected by the current order status |
BC_INVALID_ORDER_STATUS() | Operation not allowed in the current order status |
BC_ADDRESS_BOUND_TO_OTHER_BROADCASTER | _userSettlementFromAddress is currently bound to another broadcaster |
Reference implementation
BroadcasterService — example using @bronlabs/intents-sdk and ethers:
https://github.com/bronlabs-intents/intents-broadcaster-example