chain-insights 0.56.17 → 0.56.18

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chain-insights",
3
- "version": "0.56.17",
3
+ "version": "0.56.18",
4
4
  "description": "AML investigation CLI and MCP proxy for blockchain risk screening and Chain Insights Graph access",
5
5
  "homepage": "https://chain-insights.ai",
6
6
  "repository": {
@@ -101,7 +101,7 @@ Route by what the question names: an address, a pair with a day, a transaction o
101
101
  3. I want the chain's own record of a transaction by its `tx_id`, a block by its `block_height` or `block_hash`, an address at one block (`Address`), or the head: `USE chain`.
102
102
 
103
103
  `USE chain` with `Address` reads the balance, the nonce or the kind of one address, now or at a past block with `at_block`. A past block must be at least `chain_admission.at_block_min_depth` blocks below the tip. To find the counterparties of an address, search `USE topology`, then read the pair and one day on `USE facts`.
104
- A transaction is a chain question: read it on `USE chain` by its `tx_id`. Chain gives its `block_date`; the transfers between a pair on that day are a `USE facts` read.
104
+ A transaction is a chain question: read it on `USE chain` by its `tx_id`. Chain gives its `block_date`; the transfers between a pair on that day are a `USE facts` read. "Every token that moved inside this transaction": read the chain record for `from_address`, `to_address` and `block_date`, then the facts `TRANSFER` rows of that pair on that day and keep the rows whose `tx_id` matches; a `kind` of `internal` is ETH a contract moved while it ran. Tokens the transaction moved between other pairs are not reachable from the hash alone: say so, and name the pairs you did read.
105
105
  The layers hand each other keys, and each key keeps its name. Topology gives the pair and the first and last seen time. Facts gives the `tx_id` and the `block_height`. Chain takes an `address`, a `tx_id`, a `block_height` or a `block_hash`, and gives the `block_date` of a transaction or a block.
106
106
  A question about the whole chain (recent activity, the biggest senders, a top list) is a `USE topology` search: bound it by time with `f.last_seen_timestamp >= <epoch ms>` on the `FLOWS_TO` link, then sort and `LIMIT`. A search has 10 s. Read `Head` first (`USE chain MATCH (h:Head) RETURN h.graph_blocks_behind`, under a second): when `graph_blocks_behind` is above 100000 (a few hours of blocks: a robinhood block is about a tenth of a second apart from the next), the search cannot finish, so do not send it; say the graph is that many blocks behind the head and ask for an address. Never turn the block count into days or hours by head. To say how fresh the data is, give the newest `_utc` time you read on the layer you used: `graph_blocks_behind` counts the slowest graph layer, and the links of an address and the facts rows are often newer than it. If the server refuses the search with `anchor_missing`, or stops it with `query_timeout`, it cannot search the whole chain now: say so in one line and ask for an address. A narrower window times out the same way, so do not send it again.
107
107
 
@@ -174,6 +174,7 @@ bridges and the `LINKED` overlay. The server checks these before it runs:
174
174
  - Paths use bounded quantifiers such as `-[:FLOWS_TO]-{1,5}`. A `*` range, the legacy path functions, `PROFILE`, writes and `CALL` are refused.
175
175
  - Role flags `is_exchange`, `is_scam`, `is_victim` and `is_sanctioned` are absent unless true: use `IS NULL` or `IS NOT NULL`, never `= false`.
176
176
  - A kind label sits beside `:Address`: `WHERE a:Contract` or `WHERE a:Account` tests it, as `:Pool` is tested. It is no anchor.
177
+ - A `FLOWS_TO` read written without an arrow, `-[f:FLOWS_TO]-`, matches both directions and tells you nothing about which end sent. Return `startNode(f).address AS from_address, endNode(f).address AS to_address`, or send two directed reads, before you call either address the sender: one answer named the receiver as the sender and had to take it back.
177
178
 
178
179
  ## Graph searches
179
180
 
@@ -347,6 +348,7 @@ The server serves five read-only catalog calls: `CALL db.labels()`, `CALL db.rel
347
348
  - A reply holds at most 200 rows, whatever the `LIMIT`. When `count()` says the day holds more, give the count and one page, and say that the rest takes one read per 200 rows (a `t.block_timestamp >=` bound after the last row of the page). Read on only when the user asks for every row, and never beyond 5 pages in one turn: a loop of 61 reads once cost a user 131 seconds for one answer.
348
349
  - A facts read has one relationship and no hop. For a walk, go to topology.
349
350
  - A facts read takes no `ORDER BY`. Rows come in the server's own order. Sort the page yourself.
351
+ - "The largest transfer" of an address or a pair has no read: facts serves no `max()` and no sort, and the lifetime link totals hold no single transfer. Ask for the day, then read that day's rows and pick the largest yourself; or give the biggest counterparty link instead and say that is a lifetime total, not one transfer. Never read every day of a pair to find it: one answer took 190 seconds that way.
350
352
  - A facts read aggregates with `count()` and `sum()` only, over the whole page: no grouping key, no `min()`, `max()` or `avg()` (`unsupported facts query shape`). Read the rows and compute the rest yourself.
351
353
  - Every row and both endpoints carry `network`, the query's `network`. A filter on it is no anchor: it never replaces the pair and the day.
352
354
  - Facts serves no kind. A read that names `:Account` or `:Contract` is refused with `facts_no_anchor`: ask `USE topology` for the kind, or `USE chain` for `is_contract` and `nonce`.