API Oracle
Версия 0.3.0: расстояние по направленным подпискам и отдельные публичные сведения об игнорировании через HTTP. Расширение не требуется.
Публичный сервер и формат запросов
Базовый URL: https://wot-oracle.mappingbitcoin.com. Oracle не требует ключа API.
Передавайте публичные ключи в виде полных шестнадцатеричных строк из 64 символов в нижнем регистре, а не npub. В примерах используются вымышленные ключи для демонстрации формата ответов; результаты для вашего графа будут отличаться. Запросы POST используют Content-Type: application/json.
Корневой эндпоинт GET / показывает версию сервиса, документацию и доступные эндпоинты. Для своего экземпляра см. руководство по самостоятельному размещению.
Расстояния рассчитываются по направленным рёбрам подписок kind-3. Публичные списки игнорирования kind-10000 являются отдельными наблюдениями. Oracle не объединяет их в оценку доверия и не удаляет игнорируемые аккаунты из путей подписок.
Эндпоинты
GET/health
Работоспособность процесса и версия выпуска.
{
"status": "healthy",
"version": "0.3.0"
}Исправный процесс может всё ещё ожидать события от реле или не иметь возможности сохранять обновления. Используйте /ready для проверки готовности приёма данных.
GET/ready
Состояние приёма данных: HTTP 200 при готовности, иначе HTTP 503.
Готовность требует работающего приёма данных, отсутствия текущей ошибки базы данных и получения события подписок или игнорирования за последние пять минут. Поэтому неактивное частное реле может давать 503 даже при работающем процессе. Пример ожидания первого события:
{
"running": true,
"ready": false,
"last_event_received_at": 0,
"last_persisted_at": 0,
"persisted_events": 0,
"lagged_notifications": 0,
"persistence_errors": 0,
"coverage": "configured_relays_only"
}Временные метки указаны в секундах Unix; ноль означает, что событие ещё не наблюдалось. persisted_events считает принятые обновления авторов, записанные в хранилище после объединения пакетов. lagged_notifications и persistence_errors отражают проблемы приёма данных.
GET/stats
Количество элементов индексированного графа, настройки кэша, метрики блокировок и состояние приёма данных.
{
"node_count": 3,
"edge_count": 2,
"nodes_with_follows": 2,
"mute_edge_count": 0,
"nodes_with_mute_lists": 1,
"sync": {
"running": true,
"ready": false,
"last_event_received_at": 0,
"last_persisted_at": 0,
"persisted_events": 0,
"lagged_notifications": 0,
"persistence_errors": 0,
"coverage": "configured_relays_only"
},
"cache": {
"size": 0,
"capacity": 100000,
"ttl_secs": 300
},
"locks": {
"write_lock_count": 0,
"write_lock_avg_us": 0,
"write_lock_max_us": 0,
"read_lock_count": 0,
"read_lock_avg_us": 0,
"read_lock_max_us": 0
}
}Числа и настройки выше приведены для примера. edge_count считает рёбра подписок; mute_edge_count считает публичные рёбра игнорирования публичных ключей. nodes_with_mute_lists включает известные списки без открытых записей публичных ключей. Время блокировок указано в микросекундах. Объект sync имеет те же поля, что и /ready.
GET/distance
Кратчайшее расстояние по направленным подпискам от одного публичного ключа до другого.
fromиto: обязательные публичные ключи источника и получателя.max_hops: от 1 до 5, по умолчанию 3.include_bridges: логическое значение, по умолчанию false. Включает узлы встречи поиска, если они доступны.bypass_cache: логическое значение, по умолчанию false. Пересчитывает результат по текущему индексированному графу; не запрашивает новые данные у реле.
{
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"hops": 2,
"path_count": 1,
"mutual_follow": false
}hops равно нулю для расстояния до самого себя и единице для прямой подписки. Значение null означает, что в индексированном графе не найден путь в пределах запрошенной глубины. Это не доказывает отсутствие связи в других частях Nostr.
path_count считает кратчайшие направленные пути, в том числе когда мосты не включены; счётчик ограничен максимальным беззнаковым 64-битным целым. mutual_follow обозначает прямую подписку в обоих направлениях. Необязательное поле bridges содержит узлы встречи поиска, а не полный путь или доказательство непересекающихся путей.
POST/distance/batch
Запросите до 100 получателей от одного источника с сохранением их порядка и повторений.
Обязательные поля JSON: from и targets. Необязательные max_hops, include_bridges и bypass_cache используют те же значения по умолчанию, что и /distance.
Запрос
{
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"targets": [
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
],
"max_hops": 3
}Ответ
{
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"results": [
{
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"hops": 2,
"path_count": 1,
"mutual_follow": false
}
]
}Каждый результат включает from и to.
GET/path
Возвращает промежуточные публичные ключи на одном из кратчайших направленных путей подписок.
Обязательные from и to; необязательный max_hops (от 1 до 5, по умолчанию 3).
{
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"path": [
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
]
}Пример показывает два ребра подписок: от источника к мосту и от моста к получателю. Источник и получатель не входят в path. Путь к самому себе и прямая подписка возвращают пустой массив; отсутствие пути в пределах запрошенной глубины возвращает null. В этом ответе нет поля hops.
GET/follows
Возвращает страницы текущего индексированного списка подписок публичного ключа.
Обязательный параметр pubkey; необязательные offset (по умолчанию 0) и limit (по умолчанию 500, максимум 5000). total означает полный размер индексированного списка независимо от размера страницы.
{
"pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"follows": [
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
],
"total": 1
}Неизвестный публичный ключ возвращает пустой список и total: 0.
GET/common-follows
Возвращает публичные ключи, на которые напрямую подписаны оба аккаунта.
Обязательные параметры: from и to.
{
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"common_follows": [
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
]
}GET/mutes
Возвращает страницы открытых записей публичных ключей из индексированного списка игнорирования kind-10000.
Обязательный параметр pubkey; необязательные offset (по умолчанию 0) и limit (по умолчанию 500, максимум 5000). total означает полный размер индексированного списка независимо от размера страницы.
{
"pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"mutes": [],
"total": 0,
"public_list_known": true
}public_list_known: false означает, что для этого публичного ключа не было индексировано событие списка игнорирования. Известное событие может не иметь открытых записей публичных ключей, как показано выше. Зашифрованные записи игнорирования недоступны Oracle, и известный пустой публичный список всё равно может содержать зашифрованные записи. Теги игнорирования слов, хештегов и обсуждений не входят в сведения о публичных ключах.
GET/trust
Возвращает расстояние по подпискам вместе с отдельными публичными наблюдениями об игнорировании.
fromиto: обязательные публичные ключи источника и получателя.max_hops: от 1 до 5, по умолчанию 3.include_bridges: логическое значение, по умолчанию false. Включает узлы встречи поиска, если они доступны.bypass_cache: логическое значение, по умолчанию false. Пересчитывает результат по текущему индексированному графу; не запрашивает новые данные у реле.
{
"follow_distance": {
"from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"hops": 2,
"path_count": 1,
"mutual_follow": false
},
"public_mute_evidence": {
"source_mutes_target": false,
"target_mutes_source": false,
"followed_muters": [
"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
],
"source_mute_list_known": true,
"target_mute_list_known": false
}
}followed_muters перечисляет аккаунты, на которые напрямую подписан источник и чьи индексированные публичные списки игнорирования содержат получателя. Два логических значения прямого игнорирования описывают отношения источника и получателя; флаги известных списков различают отсутствующие и известные публичные списки.
Игнорирование может выражать личные предпочтения. Отсутствие публичных сведений не означает одобрения. Клиенты сами решают, как использовать эти наблюдения: ответ не назначает веса, общую оценку или автоматическое исключение. Во время приёма данных расстояние по подпискам и сведения об игнорировании могут считываться в немного разные моменты.
Охват и актуальность
sync.coverage равно configured_relays_only. Результаты описывают события, индексированные с настроенных на сервере реле, без гарантии глобального или полного охвата. Записи кэша становятся недействительными при изменении ревизии графа. Ни готовность, ни обход кэша не гарантируют, что реле вернули последнее событие.
Кэширование профилей kind-0, /profiles и include_profiles не реализованы в версии 0.3.0.
Ограничения и ошибки
Эндпоинты данных используют ограничитель token bucket для каждого IP, настроенный через RATE_LIMIT_PER_MINUTE. Лимиты зависят от развёртывания; после всплеска запросы могут отклоняться ещё до истечения минуты. Корневой маршрут, /health и /ready освобождены от этого ограничения. Тело запроса ограничено 1 MiB. Не рассчитывайте на наличие заголовков ограничения частоты в каждом ответе.
Ошибки проверки и вычислений приложения возвращают JSON с error и code:
{
"error": "Invalid pubkey format",
"code": "INVALID_PUBKEY"
}- 400:
INVALID_PUBKEY,INVALID_MAX_HOPSилиTOO_MANY_TARGETS. - 413: тело запроса превышает ограничение размера.
- 429: превышен лимит запросов для IP. Подождите перед повторной попыткой; соблюдайте указанный интервал, если он предоставлен.
- 500:
INTERNAL_ERROR. - 503:
QUERY_BUSYпри исчерпании ресурсов для запросов либо состояние готовности сready: falseот/ready.
Некорректные строки запроса, некорректный JSON и отклонения промежуточным ПО могут использовать другой формат тела. Проверяйте статус HTTP перед разбором успешного ответа. При временной перегрузке ограничивайте число повторных попыток и увеличивайте интервалы между ними.