DEX Events
XRNotify monitors the XRPL decentralized exchange (DEX), a native on-ledger order book that lets any account trade any two assets without a centralized intermediary. Offers are limit orders; when two compatible offers cross, a trade executes automatically as part of ledger consensus.
Amount format: All amount fields in DEX events are either a string representing drops of XRP (e.g. "1000000"), or an object { currency, value, issuer } for issued tokens. Never a number.
dex.offer_created
OfferCreateFires when an OfferCreate transaction places a new limit order on the DEX. The offer remains open on the order book until it is fully filled, cancelled, or expires. If the offer partially crosses on creation, a dex.offer_partial event is also emitted.
Payload schema
| Field | Type | Description |
|---|---|---|
| offer_id | number | Offer sequence number (account sequence at time of creation) |
| account | string | Account address that placed the offer |
| taker_pays | string | object | Amount the offer creator will pay when the offer is consumed (what the taker receives) |
| taker_gets | string | object | Amount the offer creator will receive when the offer is consumed (what the taker pays) |
| expiration | string | null | ISO 8601 expiry timestamp, or null for no expiry |
| flags | number | Raw transaction flags bitmask |
| is_passive | boolean | True if this is a passive offer that will not consume crossing offers at creation |
| is_fill_or_kill | boolean | True if the offer must be fully filled immediately or cancelled entirely |
| is_immediate_or_cancel | boolean | True if the offer fills what it can immediately then cancels any remainder |
| ledger_index | number | Ledger in which the offer was placed |
| tx_hash | string | Transaction hash |
Example payload
{
"event_id": "xrpl:89560000:A1B2C3D4E5F6:dex.offer_created",
"event_type": "dex.offer_created",
"ledger_index": 89560000,
"timestamp": "2024-01-15T14:00:00Z",
"network": "mainnet",
"payload": {
"offer_id": 87654321,
"account": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"taker_pays": {
"currency": "USD",
"value": "100.00",
"issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq"
},
"taker_gets": "50000000",
"expiration": null,
"flags": 0,
"is_passive": false,
"is_fill_or_kill": false,
"is_immediate_or_cancel": false,
"ledger_index": 89560000,
"tx_hash": "A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2C3D4E5F6A1B2"
}
}dex.offer_cancelled
OfferCancel / auto-expiredFires when an offer is removed from the order book, either explicitly via an OfferCancel transaction, or automatically when an expiry time passes and the ledger removes the offer during the next close.
Payload schema
| Field | Type | Description |
|---|---|---|
| offer_id | number | Sequence number of the cancelled offer |
| account | string | Owner of the cancelled offer |
| ledger_index | number | Ledger in which cancellation occurred |
| tx_hash | string | Transaction hash (the OfferCancel tx, or the tx that triggered auto-removal) |
dex.offer_filled
Trade - fully consumedFires when an offer on the order book is completely consumed by a crossing trade. The offer no longer exists on the ledger after this event. Both the offer creator and the taker receive these events when account filters match.
Payload schema
| Field | Type | Description |
|---|---|---|
| offer_id | number | Sequence number of the fully-filled offer |
| account | string | Account that originally placed the offer |
| taker_pays_actual | string | object | Exact amount paid by the taker in this fill |
| taker_gets_actual | string | object | Exact amount received by the taker in this fill |
| fill_amount | string | object | Total traded amount (equivalent to taker_gets_actual for a complete fill) |
| ledger_index | number | Ledger in which the fill was validated |
| tx_hash | string | Transaction hash of the crossing trade |
Example payload
{
"event_id": "xrpl:89561500:B3C4D5E6F7A8:dex.offer_filled",
"event_type": "dex.offer_filled",
"ledger_index": 89561500,
"timestamp": "2024-01-15T14:30:00Z",
"network": "mainnet",
"payload": {
"offer_id": 87654321,
"account": "rPT1Sjq2YGrBMTttX4GZHjKu9dyfzbpAYe",
"taker_pays_actual": {
"currency": "USD",
"value": "100.00",
"issuer": "rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq"
},
"taker_gets_actual": "50000000",
"fill_amount": "50000000",
"ledger_index": 89561500,
"tx_hash": "B3C4D5E6F7A8B3C4D5E6F7A8B3C4D5E6F7A8B3C4D5E6F7A8B3C4D5E6F7A8B3C4"
}
}dex.offer_partial
Trade - partially consumedFires when an offer is partially filled by a crossing trade but remains on the order book with a reduced amount. The offer continues to exist and will fire additional dex.offer_partial or dex.offer_filled events as more trades cross it.
Payload schema
| Field | Type | Description |
|---|---|---|
| offer_id | number | Sequence number of the partially-filled offer |
| account | string | Account that placed the offer |
| taker_pays_actual | string | object | Amount paid by the taker in this partial fill |
| taker_gets_actual | string | object | Amount received by the taker in this partial fill |
| remaining | string | object | Amount still unfilled, representing what remains on the order book |
| fill_percent | number | Percentage filled in this event (0–100), as a float |
| ledger_index | number | Ledger in which the partial fill occurred |
| tx_hash | string | Transaction hash of the crossing trade |