Events
The SDK emits events on both individual swaps and the top-level swapper. Use them for real-time UI state, pending swap tracking, analytics, LP monitoring, and route-limit refreshes.
See the complete working example: utils/events.ts
Event Emitters
The SDK uses the standard javascript EventEmitter pattern in both places - individual swaps and the overall Swapper instance:
swapperitself extendsEventEmitter, so you can subscribe directly withswapper.on(...).- Each
ISwapexposes its ownEventEmitteronswap.events, using the sameon(...)/off(...)API.
Here is a list of the SDK emitted events on the individual swaps and on the Swapper instance:
| Emitter | Event | Payload | Description |
|---|---|---|---|
ISwap.events | swapState | ISwap | The specific swap changed state |
Swapper | swapState | ISwap | Any tracked swap changed state |
Swapper | swapLimitsChanged | none | Swap minimum / maximum limits changed |
Swapper | lpsAdded | Intermediary[] | New LPs were discovered |
Swapper | lpsRemoved | Intermediary[] | Known LPs were removed |
Example snippet showing how to add new event listeners using the .on() method and remove existing listeners using the .off() method.
import {ISwap, Intermediary} from "@atomiqlabs/sdk";
// Create functions that will fire on events
const handleSwapState = (updatedSwap: ISwap) => {
console.log("Swap state changed:", updatedSwap.getStateInfo().name);
};
const handleLpsAdded = (lps: Intermediary[]) => {
console.log("New LPs discovered:", lps.length);
};
// Subscribe to relevant events on the swapper instance directly
swapper.on("swapState", handleSwapState); // Fires for all swap state changes
swapper.on("lpsAdded", handleLpsAdded);
// Or subscribe directly on a specific swap instance
swap.events.on("swapState", handleSwapState); // Fires only when the specific swap's state changes
// Later, unsubscribe with the same handler reference
swapper.off("swapState", handleSwapState);
swapper.off("lpsAdded", handleLpsAdded);
swap.events.off("swapState", handleSwapState);
For the meaning of individual swap states, see the swap-specific guides under Swap Tutorials.
Listening to a Single Swap
Each swap exposes an events emitter. The event payload is the current swap instance, so the usual pattern is to re-read the state through getState() or getStateInfo().
import {ISwap} from "@atomiqlabs/sdk";
const handleSwapState = (updatedSwap: ISwap) => {
const state = updatedSwap.getState();
const info = updatedSwap.getStateInfo();
console.log("Swap ID:", updatedSwap.getId());
console.log("State:", state, info.name);
console.log("Description:", info.description);
};
swap.events.on("swapState", handleSwapState);
// Later, unsubscribe
swap.events.off("swapState", handleSwapState);
This is the right choice when a screen or component is focused on a single known swap.
Listening on the Whole Swapper
The top-level swapper aggregates swap state changes across all currently tracked swaps and also emits system-level events for LP discovery and swap minimum / maximum limit updates.
Global swap state updates
swapState triggers when any of the tracked swaps changes state, allowing you to track states of all currently active swaps. This is useful for updating the pending swaps list or for notifications.
swapper.on("swapState", (updatedSwap) => {
const info = updatedSwap.getStateInfo();
console.log(
`Swap ${updatedSwap.getId()} changed to ${info.name}: ${info.description}`
);
});
Swap limit updates
swapLimitsChanged is emitted when the known bounds for one or more routes change. This can happen because:
- new LPs were discovered or existing LPs disappeared.
- an LP returned updated min/max bounds after a quote failed as out of range.
swapper.on("swapLimitsChanged", () => {
const limits = swapper.getSwapLimits(srcToken, dstToken);
updateLimitUI(limits);
});
For more details on swap limits, see Swap Limits.
LP discovery updates
If your UI exposes LP status or route availability, you can also listen for LP discovery events directly:
swapper.on("lpsAdded", (lps) => {
console.log("LPs added:", lps.map(lp => lp.url));
});
swapper.on("lpsRemoved", (lps) => {
console.log("LPs removed:", lps.map(lp => lp.url));
});
In most apps, swapLimitsChanged is enough for route refreshes. The LP events are mainly useful when you want to show LP availability explicitly or log discovery changes.
Best Practices
- always unsubscribe listeners when a component unmounts or when you stop tracking a swap.
- treat the emitted swap object in
swapStateevent as the source of truth and re-read derived values through getters such asgetStateInfo(),getInput(), orgetOutput(). - use
swapLimitsChangedto dynamically update your UI with newer swap minimum / maximum limits
API Reference
- ISwap.events - Per-swap event emitter
- getState - Get current numeric state
- getStateInfo - Get human-readable state info
- Swapper - Top-level SDK client exposing global events
- getSwapLimits - Re-read route limits after
swapLimitsChanged
Next Steps
Swap Limits
Use swapLimitsChanged together with the route-bound helpers when building quote forms.