chain-insights 0.37.0 → 0.37.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,6 +31,33 @@ errors `topology_busy` (retry later), `query_timeout` (anchor on an address,
31
31
  use fewer hops or a tighter `LIMIT`), and `query_memory_limit` (return fewer
32
32
  rows or properties) mean the query was stopped, not that data is missing.
33
33
 
34
+ A topology read that filters on a link property needs an address anchor. With
35
+ no address in its pattern, the read starts from every link of the type it
36
+ names. Do not count on the filter to narrow that. `WHERE x.strength = 'swap'`
37
+ on `SWAPPED` checks every `SWAPPED` link. `LIMIT` stops the read only after it
38
+ has found enough rows, so a filter that matches few or none can run to the
39
+ 60-second limit and fail with `query_timeout`. A discovery probe with no
40
+ filter, such as
41
+ `MATCH (:Address)-[r:FLOWS_TO]->(:Address) RETURN r.tx_count LIMIT 20`, finds
42
+ its rows at once and stays valid.
43
+
44
+ Put an address in the pattern, and pick one with few links. Read `degree_out`
45
+ and `degree_in` on the node first. They are a rough guide, not a guarantee:
46
+ they count neighbours, not links, and one pair of addresses can hold many
47
+ `SWAPPED` links. An address with hundreds of thousands of neighbours can fail
48
+ the same way. The queries of one batch share a 100-second budget.
49
+
50
+ Anchored on one address:
51
+
52
+ ```cypher
53
+ USE topology
54
+ MATCH (a:Address {address: "0x…"})-[x:SWAPPED]->(b:Address)
55
+ WHERE x.swap_count >= 2
56
+ RETURN b.address AS recipient, x.swap_count AS swap_count
57
+ ORDER BY x.swap_count DESC
58
+ LIMIT 25
59
+ ```
60
+
34
61
  ## Layer choice
35
62
 
36
63
  | Graph | Backend | Dialect |
@@ -167,6 +194,11 @@ Swap attribution is read from `SWAPPED`, the aggregate (`strength`, `pools`,
167
194
  `families`), or from the facts `SWAP` row, one route. `FLOWS_TO` carries value
168
195
  only.
169
196
 
197
+ Today every served swap has `strength` `swap_like` and `families` `unknown`.
198
+ Do not filter on `strength = 'swap'`: it matches nothing. A swap that could
199
+ not be paired (`swap_unsplit`) has no edge and no row. Every Uniswap v4 swap
200
+ is one. Load `chain-insights-schema-evm` for what each strength means.
201
+
170
202
  A trace that reaches a `:Pool` follows the pool trace rule in
171
203
  `chain-insights-schema-evm`. The probes below follow it.
172
204
 
@@ -208,7 +240,10 @@ LIMIT 10
208
240
  ```
209
241
 
210
242
  Raw amounts (`*_raw`) are exact token quantities, not USD. USD comes from the
211
- daily price services and is empty when no service prices the asset.
243
+ daily price services. On a facts row it is empty when no service prices the
244
+ asset, and the matching `…price_missing` is true. On `SWAPPED` it sums the
245
+ routes, and a side with no price adds 0, so 0 can mean no price. Read the
246
+ facts `SWAP` row to tell.
212
247
 
213
248
  ## Hard stops
214
249
 
@@ -48,6 +48,18 @@ other names: see [Facts labels and relationships](#facts-labels-and-relationship
48
48
 
49
49
  One edge holds the lifetime totals of one pair. Single events are facts rows.
50
50
 
51
+ ## Bookkeeping fields on links
52
+
53
+ These fields show up in `keys()`. They are not part of the contract. Do not
54
+ filter, sort or group on them.
55
+
56
+ | Field | On | Meaning |
57
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
58
+ | `synced_through_height` | `FLOWS_TO`, `SWAPPED`, `OPERATED_BY`, `ADDED_LIQUIDITY`, `REMOVED_LIQUIDITY`, `BRIDGED`, `APPROVED`, `SPONSORED`, `BUNDLED`, `SIGNED_FOR` | End block of the last sync range added into the link. The link holds every event up to this block. `graph_progress` in `meta_network_capabilities` says how far each kind of link has been synced. |
59
+ | `pair_key` | `FLOWS_TO`, `SWAPPED` | Lookup key the sync builds from the ids of the two nodes. It can change when the graph is rebuilt. |
60
+
61
+ `LINKED`, `DEPLOYED_CONTRACT` and `SIGNED_AUTHORIZATION` carry neither field.
62
+
51
63
  ## Address properties
52
64
 
53
65
  | Property | Notes |
@@ -65,6 +77,12 @@ One edge holds the lifetime totals of one pair. Single events are facts rows.
65
77
 
66
78
  There is no `AddressLabel` node and no `HAS_LABEL` or `HAS_RISK_SCORE` edge.
67
79
 
80
+ A contract address also carries `is_contract` and the creation fields
81
+ `contract_creation_tx_id`, `contract_creation_type`,
82
+ `contract_creation_confidence`, `contract_creation_block_height` and
83
+ `contract_creation_timestamp`. They come from its newest creation.
84
+ `is_contract` is `true` or absent.
85
+
68
86
  `UNSCORED` means the model gave the address no verdict: it has no
69
87
  `risk_score`, and a run that dropped it writes `risk_level` `UNSCORED`. Read
70
88
  it as no signal. Never read it as low risk.
@@ -109,15 +127,23 @@ LIMIT 1
109
127
 
110
128
  Lifetime aggregates. USD only. Do not use native `amount_sum`.
111
129
 
112
- | Property | Notes |
113
- | ---------------------------------------------- | --------------------------- |
114
- | `tx_count` | Transfer count on the pair. |
115
- | `amount_usd_sum` | Lifetime USD. |
116
- | `first_seen_timestamp` / `last_seen_timestamp` | First and last flow time. |
130
+ | Property | Notes |
131
+ | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
132
+ | `tx_count` | Count on the pair: token and native transfers plus internal native transfers (a contract sending ETH during a call, such as the ETH leg of a wrap). |
133
+ | `amount_usd_sum` | Lifetime USD, internal native transfers included. |
134
+ | `first_seen_timestamp` / `last_seen_timestamp` | First and last flow time. |
135
+
136
+ `FLOWS_TO` carries value only. Its `pair_key` and `synced_through_height` are
137
+ [bookkeeping](#bookkeeping-fields-on-links). Compute an average inline:
138
+ `amount_usd_sum / toFloat(tx_count)`.
117
139
 
118
- `FLOWS_TO` carries value only. Compute an average inline:
119
- `amount_usd_sum / toFloat(tx_count)`. A flow's transactions are `TRANSFER` rows
120
- on `USE facts`: see [Facts labels and relationships](#facts-labels-and-relationships).
140
+ `tx_count` counts token and native transfers and also internal native
141
+ transfers. `USE facts` `TRANSFER` lists the first group only. No MCP read
142
+ lists an internal native transfer yet, so a pair can have a `tx_count` above
143
+ 0 and no `TRANSFER` row. An address-only `TRANSFER` read covers a recent
144
+ window (90 days today), and a link covers all time: bound the read with
145
+ `block_date` to read further back. See
146
+ [Facts labels and relationships](#facts-labels-and-relationships).
121
147
 
122
148
  `FLOWS_TO` into and out of pools stays as it is. A pool is a real
123
149
  counterparty. Follow the [pool trace rule](#pool-trace-rule) when a trace
@@ -192,25 +218,60 @@ Swap attribution is read from `SWAPPED`, the aggregate (`strength`, `pools`,
192
218
  `families`), or from the facts `SWAP` row, one route. `FLOWS_TO` carries value
193
219
  only, so it holds no swap stamp.
194
220
 
195
- | Property | Notes |
196
- | ---------------------------------------- | -------------------------------------------------------------- |
197
- | `sold_asset` / `bought_asset` | Asset contract. `native` is the chain's native asset. |
198
- | `swap_count` | Routes summed on the edge. |
199
- | `sold_amount_raw` / `bought_amount_raw` | Exact raw token quantities, not USD. |
200
- | `sold_usd` / `bought_usd` | USD at the daily price. Empty when no price service covers it. |
201
- | `pools` | Pool addresses the routes used. |
202
- | `families` | Protocol families, for example `uniswap-v2`, or `unknown`. |
203
- | `strength` | The weakest route counted: `swap` or `swap_like`. |
204
- | `first_seen_height` / `last_seen_height` | First and last block height. |
221
+ | Property | Notes |
222
+ | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
223
+ | `sold_asset` / `bought_asset` | Asset contract. `native` is the chain's native asset. |
224
+ | `swap_count` | Routes summed on the edge. |
225
+ | `sold_amount_raw` / `bought_amount_raw` | Exact raw token quantities, not USD. |
226
+ | `sold_usd` / `bought_usd` | USD at the day price, summed over the routes on the edge. A route side with no price adds 0, so 0 can mean no price. Do not read 0 as worth nothing. |
227
+ | `pools` | Pool addresses the routes used. |
228
+ | `families` | Protocol families. Today every route reads `unknown`. |
229
+ | `strength` | The weakest route counted: `swap` or `swap_like`. Today always `swap_like`. |
230
+ | `first_seen_height` / `last_seen_height` | First and last block height. |
205
231
 
206
232
  - `swap`: the complete route is proven. Payer, recipient, assets, exact raw
207
- amounts and conservation all check out.
208
- - `swap_like`: the shape is a swap, but the pool matches no reviewed family.
209
- The money moved. The protocol is unidentified.
210
-
211
- A route whose legs could not be paired makes no edge and no facts row. A
233
+ amounts and conservation all check out. The proof needs an execution trace
234
+ (the record of the calls inside a transaction).
235
+ - `swap_like`: the shape is a swap and the money moved. The pool's code is
236
+ not proven, so no protocol is named.
237
+
238
+ Today no route is `swap`. The swap reader reads transaction receipts only,
239
+ with no execution trace. Every served route is `swap_like`, with `reason`
240
+ `unknown_pool_code` and `families` `unknown`. A Uniswap V2 or V3 swap reads
241
+ this way. `unknown` does not mean the protocol is unsupported. A filter on
242
+ `strength = 'swap'` or on a known family matches nothing.
243
+
244
+ A route whose legs could not be paired has strength `swap_unsplit`. It has no
245
+ payer, recipient or pool: without a trace the reader cannot tell who paid
246
+ whom. It exists in the warehouse only. It makes no edge and no facts row.
247
+ `strength` is `swap` or `swap_like` on `SWAPPED` and on facts `SWAP`. A
212
248
  missing `SWAPPED` edge is not proof that no swap happened.
213
249
 
250
+ Three kinds of transaction read `swap_unsplit` today:
251
+
252
+ - A Uniswap v4 swap. Every one does, by design, so v4 swaps are hidden: they
253
+ make no `SWAPPED` edge and no facts `SWAP` row. They were about 95% of
254
+ `swap_unsplit` on 2026-07-26.
255
+ - An intent fill, such as a limit order that a settlement contract fills. It
256
+ has no pool.
257
+ - A Uniswap V2 or V3 swap whose token movements do not form one input and one
258
+ output.
259
+
260
+ The `swap_unsplit` share of a day's swap routes rises with Uniswap v4 use: 1%
261
+ on 2026-06-18, 7% on 2026-07-10, 19% on 2026-07-26 and 32% on 2026-08-10.
262
+
263
+ `sold_usd` and `bought_usd` are always numbers on a link. A route side with no
264
+ price adds 0 to the sum, and the link has no count of unpriced routes. So a
265
+ link with `bought_usd` 0 may be worth nothing, or may have no price. The
266
+ facts `SWAP` row of one route tells which. `sold_price_missing` and
267
+ `bought_price_missing` say which side had no price, and the matching
268
+ `sold_usd` or `bought_usd` is empty there. A real 0 is rare: on 2026-07-26,
269
+ 47 of 100 swap routes had no price on the bought side, and fewer than 1 in
270
+ 100 was a real 0 USD.
271
+
272
+ `pair_key` and `synced_through_height` on `SWAPPED` are
273
+ [bookkeeping](#bookkeeping-fields-on-links).
274
+
214
275
  ## ADDED_LIQUIDITY and REMOVED_LIQUIDITY properties
215
276
 
216
277
  One edge per named provider and pool, and one per pool and named receiver.
@@ -282,13 +343,26 @@ ERC-1155 share this relationship type.
282
343
 
283
344
  Topology only. Do not query `OPERATED_BY` on facts.
284
345
 
285
- | Property | Notes |
286
- | ------------------------------------------------ | ------------------------------------------------------------------------------------- |
287
- | `tx_count` | Operator-mediated transfers in the aggregate. |
288
- | `amount_usd_sum` | Lifetime USD through the operator. |
289
- | `first_seen_timestamp` / `last_seen_timestamp` | First and last mediated transfer. |
290
- | `token_standard` | `ERC20`/`ERC721`/`ERC1155` when unambiguous. Optional — mixed-standard pairs omit it. |
291
- | `owner_address` / `operator_address` / `pair_id` | Endpoint identity on the edge. |
346
+ | Property | Notes |
347
+ | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
348
+ | `tx_count` | Operator-mediated transfers in the aggregate. |
349
+ | `amount_usd_sum` | Lifetime USD through the operator. |
350
+ | `first_seen_timestamp` / `last_seen_timestamp` | First and last mediated transfer. |
351
+ | `token_standard` | `ERC20`/`ERC721`/`ERC1155` when unambiguous. Optional — mixed-standard pairs omit it. |
352
+ | `owner_address` / `operator_address` / `pair_id` | Endpoint identity on the edge. |
353
+ | `valuation_tracked_count` | Transfers on the pair that are checked for a USD value: those kept with their raw amount. It can be lower than `tx_count`. |
354
+ | `valued_count` | Of those, transfers that got a USD value. |
355
+ | `missing_valuation_price_count` | Of those, transfers with no price for their day. |
356
+ | `unknown_quantity_count` | Of those, transfers whose token decimals are unknown, so the amount is unknown. |
357
+ | `unrepresentable_quantity_count` | Of those, transfers whose amount does not fit the warehouse number format. |
358
+ | `usd_range_count` | Of those, transfers whose USD value is 10^20 or more. No USD value is stored. |
359
+ | `valuation_complete` | `true` when `valued_count` equals `valuation_tracked_count`. |
360
+ | `valuation_coverage_ratio` | `valued_count` divided by `valuation_tracked_count`. 0 when none is tracked. |
361
+
362
+ `amount_usd_sum` counts a transfer with no USD value as 0. It is a floor unless
363
+ `valuation_complete` is true. The counters do not add up to
364
+ `valuation_tracked_count`: a transfer that fails a basic check is tracked, is
365
+ not valued, and sits in none of the four reason counters.
292
366
 
293
367
  `OPERATED_BY` is a topology fact. It is not proof of malicious intent and
294
368
  carries no risk label. Relayers, keeper bots, and sweepers look like drainers
@@ -313,20 +387,21 @@ LIMIT 10
313
387
 
314
388
  Call that probe `operated_by_sample` in `graph_query_batch`. Zero rows is a
315
389
  healthy result. Whole-graph high-fan-in sweeps (every operator grouped by distinct owner
316
- count) are valid but heavy: at millions of edges they exceed the hosted
317
- 10-second per-query budget and can burn metered seconds. Scope both endpoints
390
+ count) are valid but heavy: at millions of edges they can exceed the
391
+ 60-second per-query limit and burn metered seconds. Scope both endpoints
318
392
  by `network`, bound by a recent `last_seen_timestamp` window (recompute the
319
393
  cutoff), and prefer the point-anchored probe on metered endpoints.
320
394
 
321
395
  ## LINKED properties
322
396
 
323
- | Property | Notes |
324
- | ---------------- | ---------------------------------------- |
325
- | `basis` | `derived` or `associated`. |
326
- | `confidence` | Overlay confidence. |
327
- | `source_event` | Why the link exists. |
328
- | `declared_owner` | Declared controller when present. |
329
- | `last_height` | Block height of the newest owner action. |
397
+ | Property | Notes |
398
+ | ---------------- | -------------------------------------------------------------------- |
399
+ | `basis` | `derived` or `associated`. |
400
+ | `confidence` | Overlay confidence. |
401
+ | `source_event` | Why the link exists. |
402
+ | `declared_owner` | Declared controller when present. |
403
+ | `last_height` | Block height of the newest owner action. |
404
+ | `owner_state` | `added` on every link served. An owner that was removed has no link. |
330
405
 
331
406
  Use one visible `LINKED` hop, then `FLOWS_TO`. Do not collapse linked
332
407
  addresses into one node.
@@ -365,12 +440,14 @@ hold unlimited approvals too. Confirm with `FLOWS_TO` and label context.
365
440
  One link per contract creation, from the deployer to the contract. An address
366
441
  created twice has two links.
367
442
 
368
- | Property | Notes |
369
- | ---------------------------------------------------- | --------------------------------------------------------------------- |
370
- | `kind` | How the contract was created. |
371
- | `tx_id` / `block_height` / `block_timestamp` | The creation transaction. |
372
- | `deployer_address` / `factory_address` / `tx_origin` | Who deployed it, through which factory, and who sent the transaction. |
373
- | `source_event` | `contract_creation`. |
443
+ | Property | Notes |
444
+ | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
445
+ | `kind` | How the contract was created. |
446
+ | `tx_id` / `block_height` / `block_timestamp` | The creation transaction. |
447
+ | `deployer_address` / `factory_address` / `tx_origin` | Who deployed it, through which factory, and who sent the transaction. |
448
+ | `source_event` | `contract_creation`. |
449
+ | `confidence_score` | The indexer's confidence in how the creation was classified (`kind`). It is 1 on every creation today. |
450
+ | `call_type` / `amount` | Only when the creation was funded: the funding call (`CREATE` or `CREATE2`) and the native amount sent, as decimal text. Absent otherwise. |
374
451
 
375
452
  ## SPONSORED properties
376
453
 
@@ -397,10 +474,12 @@ user operations it submitted. It has the same properties as `SPONSORED`:
397
474
  One link per signing key and smart account, from the key to the account it
398
475
  signs for.
399
476
 
400
- | Property | Notes |
401
- | ------------------------------ | ---------------------------- |
402
- | `first_height` / `last_height` | First and last block height. |
403
- | `source_event` | `account_signer`. |
477
+ | Property | Notes |
478
+ | ------------------------------ | ------------------------------------------------------------------- |
479
+ | `operations` | User operations the key signed for the account, summed on the link. |
480
+ | `failed_operations` | Of those, operations whose user operation failed. |
481
+ | `first_height` / `last_height` | First and last block height. |
482
+ | `source_event` | `account_signer`. |
404
483
 
405
484
  ## SIGNED_AUTHORIZATION properties
406
485
 
@@ -439,15 +518,15 @@ link carries an earlier run's id. A pattern is a model finding, not a verdict. R
439
518
 
440
519
  ## Facts labels and relationships
441
520
 
442
- | Label / relationship | Shape | Notes |
443
- | -------------------- | ----------------------------------------------------------- | ---------------------------------------------------------- |
444
- | `Address` | — | Row endpoint only. No `network` property. No `Pool` label. |
445
- | `Asset` | — | Token or native asset. |
446
- | `TRANSFER` | `(from:Address)-[t:TRANSFER]->(to:Address)` | One transfer row. Needs an indexed predicate. |
447
- | `SWAP` | `(payer:Address)-[s:SWAP]->(recipient:Address)` | One swap route. Needs an indexed predicate. |
448
- | `LIQUIDITY_ADD` | `(provider:Address)-[l:LIQUIDITY_ADD]->(pool:Address)` | One liquidity add. Needs an indexed predicate. |
449
- | `LIQUIDITY_REMOVE` | `(pool:Address)-[l:LIQUIDITY_REMOVE]->(receiver:Address)` | One liquidity removal. Needs an indexed predicate. |
450
- | `BRIDGE_CROSSING` | `(sender:Address)-[c:BRIDGE_CROSSING]->(recipient:Address)` | One bridge event. Needs an indexed predicate. |
521
+ | Label / relationship | Shape | Notes |
522
+ | -------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
523
+ | `Address` | — | Row endpoint only. No `network` property. No `Pool` label. |
524
+ | `Asset` | — | Token or native asset. |
525
+ | `TRANSFER` | `(from:Address)-[t:TRANSFER]->(to:Address)` | One token or native transfer row. Lists no internal native transfer. Needs an indexed predicate. |
526
+ | `SWAP` | `(payer:Address)-[s:SWAP]->(recipient:Address)` | One swap route. Needs an indexed predicate. |
527
+ | `LIQUIDITY_ADD` | `(provider:Address)-[l:LIQUIDITY_ADD]->(pool:Address)` | One liquidity add. Needs an indexed predicate. |
528
+ | `LIQUIDITY_REMOVE` | `(pool:Address)-[l:LIQUIDITY_REMOVE]->(receiver:Address)` | One liquidity removal. Needs an indexed predicate. |
529
+ | `BRIDGE_CROSSING` | `(sender:Address)-[c:BRIDGE_CROSSING]->(recipient:Address)` | One bridge event. Needs an indexed predicate. |
451
530
 
452
531
  A relationship is served only where its data exists. Check
453
532
  `meta_network_capabilities` before you query one.
@@ -461,18 +540,23 @@ on either endpoint, or by a bare `block_date` bound. A `block_timestamp`
461
540
  window in epoch milliseconds narrows a `block_date` bound and is refused on
462
541
  its own.
463
542
 
543
+ An address filter with no `block_date` bound covers a recent window (90 days
544
+ today). Add a bare `block_date` bound to read older rows. `TRANSFER` lists
545
+ token and native transfers. It lists no internal native transfer: see
546
+ [`FLOWS_TO` properties](#flows_to-properties).
547
+
464
548
  `SWAP` holds one row per route of a `swap` or `swap_like` reading, self swaps
465
549
  included. Filter it by an address on either endpoint or by a `tx_id`
466
550
  equality. `block_timestamp` is epoch milliseconds, in filters and in
467
551
  results, as on `TRANSFER`.
468
552
 
469
- | Property group | Properties |
470
- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
471
- | Where | `block_date`, `block_height`, `block_timestamp`, `tx_id`, `row_index` |
472
- | Claim | `strength`, `reason` (why a claim is `swap_like`), `route_id` (ties every leg of one route together), `registry_version` |
473
- | Parties | `payer`, `recipient`, `pools` (in route order), `pool_keys`, `families` |
474
- | Sold side | `sold_asset`, `sold_asset_symbol`, `sold_decimals`, `sold_amount_raw`, `sold_amount`, `sold_price_usd`, `sold_usd`, `sold_price_missing` |
475
- | Bought side | `bought_asset`, `bought_asset_symbol`, `bought_decimals`, `bought_amount_raw`, `bought_amount`, `bought_price_usd`, `bought_usd`, `bought_price_missing` |
553
+ | Property group | Properties |
554
+ | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
555
+ | Where | `block_date`, `block_height`, `block_timestamp`, `tx_id`, `row_index` |
556
+ | Claim | `strength` (`swap` or `swap_like`), `reason` (why a claim is `swap_like`: `unknown_pool_code` today), `route_id` (ties every leg of one route together), `registry_version` |
557
+ | Parties | `payer`, `recipient`, `pools` (in route order), `pool_keys`, `families` |
558
+ | Sold side | `sold_asset`, `sold_asset_symbol`, `sold_decimals`, `sold_amount_raw`, `sold_amount`, `sold_price_usd`, `sold_usd`, `sold_price_missing` |
559
+ | Bought side | `bought_asset`, `bought_asset_symbol`, `bought_decimals`, `bought_amount_raw`, `bought_amount`, `bought_price_usd`, `bought_usd`, `bought_price_missing` |
476
560
 
477
561
  `LIQUIDITY_ADD` and `LIQUIDITY_REMOVE` hold one row per liquidity event.
478
562
  Filter them by an address on either endpoint or by a `tx_id` equality.
@@ -490,6 +574,8 @@ Filter them by an address on either endpoint or by a `tx_id` equality.
490
574
 
491
575
  `usd` sums the priced sides and is empty when neither side has a price.
492
576
  `amount0_price_missing` and `amount1_price_missing` say which side had none.
577
+ `family` on a liquidity row is `v2` or `v3`, read from the event shape. It is
578
+ not a swap family: swap `families` read `unknown` today.
493
579
 
494
580
  `BRIDGE_CROSSING` holds one row per bridge event. Filter it by a bare
495
581
  `block_date` bound or a `tx_id` equality. Properties: `block_date`,
@@ -498,8 +584,10 @@ Filter them by an address on either endpoint or by a `tx_id` equality.
498
584
  `asset_kind`, `amount_raw`, `source_kind`, `source_index`, `route_id`,
499
585
  `protocol`. It has no `block_timestamp`.
500
586
 
501
- USD comes from the daily price services, never from a swap. With no price,
502
- USD is empty and the matching `…price_missing` is true.
587
+ On a facts row, USD comes from the daily price services, never from a swap.
588
+ With no price, USD is empty and the matching `…price_missing` is true. A
589
+ topology link sums its rows and counts a side with no price as 0: see
590
+ [`SWAPPED` properties](#swapped-properties).
503
591
 
504
592
  A single-node `MATCH (a:Address)` on facts is refused. Lifetime metrics
505
593
  live on topology, not facts.