# oklink — wallet labels API

Looks up OKLink's wallet label (entity tag), risk tags and other tags for a TRON or EVM address.

Base URL: `https://ok.internal.ompfinex.cloud`

## Endpoints

| Request | What it does |
|---|---|
| `GET /<ADDRESS>` | `T…` address: TRON. `0x…` address: checks every supported EVM chain and merges the results. |
| `GET /<CHAIN>/<ADDRESS>` | One chain only (faster). `CHAIN` is OKLink's API name, see below. |
| `GET /healthz` | `ok` |
| `GET /` | This page |

`/ok/<ADDRESS>` and `/ok/<CHAIN>/<ADDRESS>` work too.

**Supported EVM chains** (checked in this order for a bare `0x…`):
`eth`, `bsc`, `polygon`, `arbitrum`, `base`, `optimism`, `avaxc` (Avalanche C), `linea`, `scroll`, `zksync`, `opbnb`, `gnosis`, `ftm` (Fantom).
TRON: `tron`.

Use these exact names. OKLink returns an empty result (not an error) for an unknown chain name.

## Examples

```bash
curl https://ok.internal.ompfinex.cloud/TZ2mxCk8BHq6bZo9XuauF15RpLKL1Ffmv6
```
```json
{"address":"TZ2mxCk8BHq6bZo9XuauF15RpLKL1Ffmv6","chain":"tron",
 "entityTag":"OMPFinex. User","hoverEntityTag":"Exchange: OMPFinex. User",
 "riskTags":["High Risk Jurisdiction"],"isRisk":true,"riskCategory":"High Risk Jurisdiction",
 "chains":{"tron":{...}},"checked":["tron"]}
```

```bash
curl https://ok.internal.ompfinex.cloud/0x28C6c06298d514Db089934071355E5743bf21d60
```
```json
{"address":"0x28c6c06298d514db089934071355e5743bf21d60","chain":"eth",
 "entityTag":"Binance. DepositAndWithdraw_1","hoverEntityTag":"Exchange: Binance. DepositAndWithdraw_1",
 "chains":{"eth":{"hoverEntityTag":"Exchange: Binance. DepositAndWithdraw_1",...},
           "bsc":{"hoverEntityTag":"Exchange: Binance. Cold Wallet_9",...}, ...},
 "checked":["eth","bsc","polygon",...]}
```

```bash
curl https://ok.internal.ompfinex.cloud/bsc/0x8894E0a0c962CB723c1976a4421c95949bE2D4E3
```

## Response fields

- **Top level:** the tags of the best chain, which is the first chain in the list above that has an entity label. `chain` says which one it is.
- **`hoverEntityTag`:** the full label, e.g. `"Exchange: Binance. Cold Wallet_9"`. `entityTag` is the same without the category.
- **`riskTags`, `isRisk`, `riskCategory`:** present when OKLink flags the address.
- **`propertyTags`, `tokenTag`, …:** other tags, when OKLink has them.
- **`chains`:** per-chain tags, only for chains where something was found.
- **`checked`:** the chains that answered.
- **`errors`:** chains that failed. Only present if some did.
- **No label:** an address OKLink has nothing on returns `200` with an empty `chains` and no label fields.

## Status codes

| Code | Meaning |
|---|---|
| `200` | Success (possibly with no tags). `X-Cache: HIT` means the result came from cache (kept 10 minutes). |
| `400` | Not a TRON or EVM address, or a malformed chain name. |
| `502` | OKLink refused the request. The body has `error`, `status`, `code` and usually a `hint`. |

## Speed and limits

- **Speed:** a single chain takes about 1–3 s. A bare `0x…` makes one OKLink request per chain, one after another (OKLink rate-limits parallel calls), so it takes about 35 s. Use `/<CHAIN>/<ADDRESS>` when you know the chain.
- **Queueing:** requests are queued and spaced 1.5 s apart, so bulk use is slow by design. Don't loop over thousands of addresses.

## If it stops working

- **`"device risk check failed"`:** OKLink no longer accepts the device id. Open any address page on oklink.com in a browser and copy the `devid` request header (DevTools → Network → any `/api/` request). On the server, put it in `/root/oklink/oklink/.env` as `OKLINK_DEVID=…`, then run `docker compose up -d`.
- **403 / `50113`:** OKLink changed its frontend code. See `NOTES.md` for how to refresh the bundles.

## Running it

- **Server:** `/root/oklink/oklink`, started with `docker compose up -d --build`, listens on `127.0.0.1:18093`. nginx serves `ok.internal.ompfinex.cloud` through Cloudflare.
- **CLI:** `docker compose run --rm oklink [-chain bsc] <ADDRESS>`, or locally `go build -o oklink . && ./oklink <ADDRESS>`. Needs Node 22 or later and `npm install` in `oklinkjs/`.
