Address Events
Monitor all on-chain activity for specific Sui addresses in real-time. Track wallet movements, protocol treasuries, or key actors in your ecosystem without polling.
Overview
Address Events let you subscribe to all on-chain changes affecting a specific Sui address. Every time an object is created, modified, transferred, or deleted at that address, you receive an instant notification via Server-Sent Events (SSE).
Surflux enriches these events with decoded object data, giving you complete visibility into what's happening at any address — including the full object state before and after each change.
Use Cases
Wallet Monitoring
- Track incoming and outgoing transactions for user wallets
- Build real-time balance updates for your app
- Monitor specific whale wallets for trading signals
Protocol Treasury Tracking
- Watch your protocol's treasury address for deposits and withdrawals
- Build alerts for significant treasury movements
- Track liquidity pool balance changes
User Activity Feeds
- Create live activity feeds showing user actions
- Monitor key actors in your dApp ecosystem
- Build reputation systems based on on-chain behavior
Security & Compliance
- Monitor addresses flagged for suspicious activity
- Track compliance-related wallet movements
- Build real-time alert systems for address activity
DeFi & Trading Bots
- Follow smart money wallets
- React instantly to large position changes
- Build copy-trading or mirror-trading systems
How to Subscribe
Endpoint
GET /events?api-key={your_api_key}&last-id={resumption_id}
Base URL (Mainnet): https://flux.surflux.dev
Base URL (Testnet): https://testnet-flux.surflux.dev
Parameters
| Parameter | Required | Description |
|---|---|---|
api-key | Yes | Your Surflux API key for authentication |
last-id | No | Resume stream from a specific event ID |
Stream Resumption with last-id
| Value | Behavior |
|---|---|
0 (default) | Start from the beginning (server buffer limits apply) |
$ | Only receive new events from now onwards |
{event-id} | Resume from after this specific event ID |
Tip: Persist the event ID from each received event. If your connection drops, use the last ID to resume without missing any address updates.
Connection Limits
Only one client per API key can be connected at a time. Contact support if you need multiple simultaneous connections.
Event Structure
Address Update Format
{
"type": "address_update",
"timestamp_ms": 1730565189365,
"checkpoint_id": 75542359,
"tx_hash": "Fw7Hk5bjtiYLVeZc6N5ZAeHur9tvfgNN6KQThD2AwFUg",
"data": {
"address": "0x1148207ed0d1b54bd24172fe0a49092c858e363e702cc32c56bd9bf50afeb952",
"new_object": {
"object_type": "0x2::coin::Coin<0x2::sui::SUI>",
"contents": {
"id": {
"id": "0xffd4afc3063c8b06ac07c2c645d65845ca0ebf4f379794cc01195db85de045e7"
},
"balance": "2997435468"
}
},
"old_object": null
}
}
Field Descriptions
| Field | Type | Description |
|---|---|---|
type | string | Always "address_update" for address events |
timestamp_ms | number | Unix timestamp in milliseconds when the change occurred |
checkpoint_id | number | Sui checkpoint number |
tx_hash | string | Transaction digest that caused this update |
data.address | string | The address being monitored |
data.new_object | object | null | The new state of the object (null if deleted) |
data.old_object | object | null | The previous state of the object (null if newly created) |
Object Structure
When an object is created or modified, the new_object and old_object fields contain:
| Field | Type | Description |
|---|---|---|
object_type | string | Full type path of the object |
contents | object | Decoded object fields and values |
Understanding Object Changes
Address events track three types of changes:
Object Created (old_object: null)
A new object was created at this address (e.g., receiving a coin or NFT).
Object Modified (both objects present) An existing object's state changed (e.g., balance update, metadata change).
Object Deleted (new_object: null)
An object was removed from this address (e.g., coin spent, NFT transferred out).
Code Examples
JavaScript / TypeScript
const apiKey = "your_api_key_here";
const monitoredAddress = "0x1148207ed0d1b54bd24172fe0a49092c858e363e702cc32c56bd9bf50afeb952";
const eventSource = new EventSource(
`https://flux.surflux.dev/events?api-key=${apiKey}&last-id=$`
);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "address_update" && data.data.address === monitoredAddress) {
const { address, new_object, old_object } = data.data;
if (old_object === null && new_object !== null) {
console.log("Object created:", new_object.object_type);
console.log("Contents:", new_object.contents);
} else if (old_object !== null && new_object !== null) {
console.log("Object modified:", new_object.object_type);
console.log("Old:", old_object.contents);
console.log("New:", new_object.contents);
} else if (new_object === null) {
console.log("Object deleted:", old_object.object_type);
}
// Persist event ID for resumption
localStorage.setItem("lastEventId", event.lastEventId);
}
};
eventSource.onerror = (error) => {
console.error("Connection error:", error);
eventSource.close();
};
Track Balance Changes
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "address_update") {
const { new_object, old_object } = data.data;
// Check if it's a SUI coin update
if (new_object?.object_type?.includes("::coin::Coin<") &&
new_object?.object_type?.includes("::sui::SUI>")) {
const oldBalance = old_object?.contents?.balance || "0";
const newBalance = new_object?.contents?.balance || "0";
const balanceChange = BigInt(newBalance) - BigInt(oldBalance);
if (balanceChange > 0) {
console.log(`Received ${balanceChange} MIST`);
} else if (balanceChange < 0) {
console.log(`Spent ${Math.abs(Number(balanceChange))} MIST`);
}
}
}
};
Best Practices
- Filter by Address — The SSE stream includes events for all addresses. Always filter by your target address(es) on the client side.
- Track Multiple Addresses — To monitor multiple addresses, filter for them in your event handler. Each address will have its own stream of
address_updateevents. - Handle Large Objects — Some objects have large
contentsfields. Consider implementing pagination or selective field extraction if processing many events. - Persist Last Event ID — Always save the event ID to resume streams after disconnections without missing updates.
- Detect Balance Changes — Compare
old_objectandnew_objectto calculate balance changes, track NFT transfers, or detect state mutations. - Build Caches — Use address events to maintain a local cache of an address's current objects, updated in real-time as events arrive.
Related Streams
- Package Events — Subscribe to smart contract event emissions
- Object Changes — Track specific object state changes