IP Cluster
Accounts grouped by a shared address or device. The shape is the finding: one node fanning out to eight accounts is multi-accounting, eight accounts each on their own address is a shared ISP.
src/components/ui/ip-cluster.tsxAbout
From the component's own source, where it was written.
Accounts grouped by a shared IP address or device.
The shape it draws is the finding: one node fanning out to eight accounts is multi-accounting; eight accounts each on their own address is a coincidence of a shared ISP. A flat list of "accounts that share an IP" cannot tell those apart, which is why this is a grouped view rather than a table.
Group sizes are printed and the list sorts largest-first, because an analyst opening this has a queue and needs the worst cluster at the top without scanning.
Residential and mobile addresses are marked. Carrier-grade NAT puts thousands of unrelated subscribers behind one address, so an unmarked shared-IP finding on a mobile network is close to meaningless — the label is what stops someone banning a whole apartment block.
Install
npx astralyx-ui add ip-cluster
Usage
import { IpCluster } from '@/components/ui/ip-cluster'
<IpCluster clusters={clusters} onSelect={openAccount} />Composer
Change the props and the source below follows.
45.83.220.11datacenterFrankfurt, DE5 accounts92.40.11.7mobile — shared by carrier NATManchester, UK3 accountsfp_7be21044c9Chrome 141 · macOS2 accounts<IpCluster clusters={clusters} onSelect={openAccount} />Examples
Accounts sharing an address
<IpCluster clusters={clusters} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
IpCluster
Extends Omit<ComponentProps<'div'>, 'children' | 'onSelect'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| clusters | Cluster[] | required | { id, value, kind?, network?, location?, members }. Sorted largest-first, because this is a queue and the worst cluster belongs at the top. |
| onSelect | (member: ClusterMember, cluster: Cluster) => void | — | Makes members real buttons. Omit for a read-only view. |
Types
ClusterMember
Accounts grouped by a shared IP address or device.
| Field | Type | Description |
|---|---|---|
| id | string | — |
| label | ReactNode | — |
| detail? | ReactNode | — |
| focus? | boolean | Marks the account under review so it stands out inside its own cluster. |
| status? | 'active' | 'banned' | 'flagged' | — |
Cluster
| Field | Type | Description |
|---|---|---|
| id | string | — |
| value | ReactNode | The shared value — an IP, a device hash, a payout wallet. |
| kind? | 'ip' | 'device' | 'account' | — |
| network? | 'residential' | 'mobile' | 'datacenter' | 'vpn' | Weighs the evidence. Carrier-grade NAT puts thousands of unrelated subscribers behind one mobile address — the label is what stops someone banning an apartment block. |
| location? | ReactNode | — |
| members | ClusterMember[] | — |