---
title: "Ring Oracle"
description: "Єдиний server-only фасад курсів для котирувань native token на desk, мостів Chainlink, фіатного FX, обліку кредитів і presentment у магазині"
locale: "uk"
---
# Ring Oracle

Ring Oracle — це server-only фасад курсів за адресою `@/lib/ring-oracle`. Він дає платіжному, wallet-, membership-, public-pool- і store-коду єдину лексику для вартості проєкту замість жорстко заданих символів токенів або фіатних валют.

> **Info**
> Використовуйте **Founder** / **Developer** на бічній панелі документації, щоб відфільтрувати цю сторінку. Засновники бачать операторський шлях і поведінку checkout; розробники — перевірені модулі, маршрути, payload-и та smoke-команди.

## Три номінали, без псевдонімів символів

| Номінал | Значення | Налаштована ідентичність |
|---|---|---|
| `credit_balance` | Одиниця ledger, якою володіє проєкт | `credit.creditBalanceUnitLabel` і `credit.creditBalanceUnitToMainCurrency` |
| `native_token` | Нативний токен клону | `tokens.nativeToken.symbol` |
| `main_currency` | Фіат розрахунків проєкту | `store.mainCurrency` |

`ValueDenomination` містить рівно ці три значення. Символи валют на кшталт `RING`, `USD` або `UAH` — це значення для display/config, а не ідентифікатори номіналів.

  `GET` і `POST /api/prices/conversion` приймають лише `native_token` і `main_currency`. `credit_balance` використовує поверхню обліку кредитів, а застарілі псевдоніми запитів `RING` / `USD` повертають HTTP 400.

### For founders

## Чому це важливо для вашого клону

  
- **[Послідовна грошова мова](/docs/features/payments.md)** — Wallet, checkout, membership і фінансування спільноти визначають вартість проєкту через ту саму модель номіналів.

  
- **[Операційний FX-потік](/docs/features/payment-conductor.md)** — ProcessConductor оновлює фіатні курси presentment, а ручні перевизначення залишаються доступними в конфігурації клону.

  
- **[Правдивий checkout](/docs/features/store.md)** — Store відокремлює те, що бачить покупець, від фіатної валюти, яку стягує картковий або PayPal-шлюз.

## Шлях оператора

### 1. Виберіть грошові ідентичності клону

Задайте основну валюту проєкту, підтримувані фіатні валюти presentment, підтримувані crypto-символи, native token і курс обліку кредитів у `ring-config.json`. Ring Oracle читає ці ідентичності проєкту; продуктовому коду не потрібен спеціальний випадок `RING/USD`.

### 2. Виберіть FX-потік

`ring-config.fx` визначає провайдерів у такому порядку:

1. `fx.byMainCurrency[store.mainCurrency]`
2. NBU, коли основна валюта — `UAH`
3. `fx.default` для інших основних валют

Поставлений за замовчуванням конфіг використовує NBU для UAH, а в інших випадках `open_er_api`. `fx.manualOverrides` має пріоритет над статичними курсами та live overlay.

### 3. Керуйте desk- і FX-курсами

Відкрийте `/admin/web3/settings` як superadmin, щоб оновити desk-курс native token, переглянути визначеного провайдера фіатного FX і час останнього отримання або примусово оновити FX. UI читає `GET /api/admin/web3/settings` і `GET /api/admin/fx`; запис відбувається відповідними `POST`-маршрутами.

### 4. Заплануйте маршрут потоку

Продакшен-планувальники викликають `GET /api/cron/fx-feed-refresh`. Встановіть `CRON_SECRET` і надішліть його як Bearer-токен. Маршрут записує запуск через ProcessConductor з ID pipeline `fx-feed-refresh`; застарілість потоку й надалі визначається налаштованим `refreshHours`.

### 5. Зрозумійте presentment покупця

Ліва навігаційна панель перемикається лише між `main_currency` (остання фіатна перевага покупця) і `native_token`. Droplist checkout дотримується цього режиму: фіат перелічує налаштовані `SupportedCurrencies`, native — налаштовані `SupportedCrypto`.

На кроці review рядки продуктів і підсумки конвертуються через `convertPrice` / `displayPrice`. Card і PayPal залишаються фіатними платежами: checkout передає фіатний `paymentCurrency`, а сервер повторно обчислює платіж із підсумку замовлення в основній валюті перед викликом PaymentConductor.

> **Tip**
> Crypto-сума в review checkout — це presentment, а не доказ того, що картковий шлюз стягне crypto. Платіжна рейка та `paymentCurrency` визначають settlement.

### For developers

## Архітектура

| Поверхня | Перевірений шлях | Відповідальність |
|---|---|---|
| Фасад | `lib/ring-oracle/index.ts` | Server-only export surface для кожного сімейства курсів |
| Номінали | `lib/value-denomination.ts` | Точна трійка `ValueDenomination` і валідація |
| Desk oracle | `features/wallet/services/native-token-oracle.ts` | Курс native ↔ main, підписані котирування, audit log |
| Міст Chainlink | `features/wallet/services/native-token-chainlink-oracle.ts` | Allowlist зовнішніх EVM token feeds |
| Фіатний FX | `lib/fx/fx-feed-service.ts`, `lib/fx/fx-rates-overlay.ts` | Визначення провайдера, постійний кеш, live overlay |
| Облік кредитів | `lib/payments/credit-balance.ts` | Хелпери обліку credit unit ↔ main |
| FX pipeline | `lib/processes/fx/fx-feed-refresh.ts`, `lib/processes/registry.ts` | Обробник, ID і cron-шлях ProcessConductor |
| API конвертації | `app/api/prices/conversion/route.ts` | Публічний контракт курсу й конвертації native ↔ main |
| SSR hydrate | `app/layout.tsx` | `AuthenticatedAppShell` прогріває й читає курси |
| Client provider | `components/providers/app-client-shell.tsx` | Передає `initialExchangeRates` у контекст валюти store |
| Контекст валюти store | `features/store/currency-context.tsx` | Режим display, конвертація, форматування, переваги |
| Presentment checkout | `features/store/components/checkout/prebilling-page.tsx` | Droplist fiat/crypto і фіатний `paymentCurrency` |
| Charge checkout | `app/_actions/store-checkout-payment.ts` | Серверний перерахунок фіату для card/PayPal |

### Правило фасаду

Серверний код імпортує курси з фасаду, а не з модулів реалізації:

{`import {
  ensureFxFeedFresh,
  getExchangeRates,
  getMainCurrencySymbol,
  getNativeTokenToMainCurrencyRate,
} from '@/lib/ring-oracle'

await ensureFxFeedFresh()
const rates = getExchangeRates()
const desk = await getNativeTokenToMainCurrencyRate()`}

`@/lib/ring-oracle` імпортує `server-only`. Клієнтські компоненти отримують серіалізовані дані курсів через `AuthenticatedAppShell`, `AppClientShell` або безпечну для клієнта server action `getLiveExchangeRates`.

## Потік оновлення FX

### Налаштуйте визначення провайдера

{`{
  "fx": {
    "byMainCurrency": {
      "UAH": {
        "provider": "nbu",
        "enabled": true,
        "refreshHours": 24
      }
    },
    "default": {
      "provider": "open_er_api",
      "enabled": true,
      "refreshHours": 24
    },
    "manualOverrides": {}
  }
}`}

ID провайдерів: `nbu`, `open_er_api` і `frankfurter`. Жорстка перевірка замінює NBU на `open_er_api`, коли основна валюта не UAH.

### Захистіть і викличте cron-маршрут

{`CRON_SECRET=replace-with-a-long-random-secret

curl \
  -H "Authorization: Bearer $CRON_SECRET" \
  https://your-ring.example/api/cron/fx-feed-refresh`}

Перевірка авторизації є умовною щодо `CRON_SECRET`, тому продакшен-розгортання мають його налаштувати. Відповідь містить `runId` ProcessConductor і метадані оновлення; вимкнений потік повертає успішний пропущений запуск. Курси зберігаються в `platform_settings` з id `fx_feed` (той самий гібридний шаблон JSONB, що й у desk oracle). Для погодинного оновлення кластера додайте `k8s/cronjob-fx-feed-refresh.yaml`.

### Перевірте або примусово оновіть як адміністратор

`GET /api/admin/fx` повертає конфігурацію визначеного потоку, перевизначення, час отримання, зразок курсів і визначені курси для адміністраторів платформи. `POST /api/admin/fx` приймає `{ "force": true }` і оновлює потік. Читання та запис desk-курсу залишаються на доступному лише superadmin маршруті `/api/admin/web3/settings`.

## Контракт API конвертації

### Прочитайте підтримувані пари

`GET /api/prices/conversion` повертає `denominations: ["native_token", "main_currency"]`, обидві пари напрямків, курси та обернені курси, метадані джерела й ліміти від `0.000001` до `1000000`.

### Конвертуйте суму

{`curl -X POST https://your-ring.example/api/prices/conversion \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "25",
    "from": "main_currency",
    "to": "native_token"
  }'`}

`amount` має бути додатним десятковим рядком, а `from` має відрізнятися від `to`. Відповідь містить ідентифікатори номіналів, налаштовані display-валюти, вихідну суму, конвертовану суму, обмінний курс, timestamp, confidence, нульову комісію конвертації та метадані джерела.

  `{ "from": "RING", "to": "USD" }` недійсний, навіть якщо це налаштовані символи клону. Надсилайте ідентифікатори номіналів, а не символи.

## Межі SSR і checkout

### Гідратуйте курси на сервері

`AuthenticatedAppShell` викликає `ensureFxFeedFresh()`, потім `getExchangeRates()`. Якщо оновлення не вдається, оболонка залишає `initialExchangeRates` рівним null, а клієнтський код переходить до статичних курсів `ring-config`.

### Заповніть і оновлюйте client provider

`AppClientShell` передає серіалізовані курси до `StorePaymentMethodsProvider`. Провайдер починає з цього SSR seed, потім після hydration викликає `getLiveExchangeRates()`, щоб конвертація в браузері залишалася узгодженою із серверним checkout.

### Розділяйте валюти display і charge

`StorePaymentMethodsProvider.displayMode` — лише `main_currency | native_token`. `PrebillingPage` формує droplist із `getSupportedCurrencies()` або `getSupportedCrypto()`, зберігаючи фіатний `paymentCurrency` для card і PayPal. `submitStoreCheckoutPayment` перевіряє цей фіат щодо підтримуваного пулу presentment і перераховує суму на сервері.

## Smoke-перевірка

Запустіть поставлений smoke `smk46_` з `ring-platform.org`:

{`NODE_OPTIONS="--conditions=react-server" \
DB_BACKEND_MODE=k8s-postgres-fcm \
npx tsx scripts/smoke-ring-oracle-fx.cts

# Include public API and cron probes:
SMOKE_BASE_URL=http://localhost:3000 \
CRON_SECRET=replace-with-the-local-secret \
npx tsx scripts/smoke-ring-oracle-fx.cts`}

Smoke перевіряє реєстрацію pipeline, визначення й оновлення провайдера, round-trip сервісу native ↔ main, необов’язкові контракти conversion `GET` / `POST`, HTTP 400 для застарілих `RING` / `USD` і поведінку cron-відповіді.

## Пов’язана документація

  
- [features/payment-conductor](/docs/features/payment-conductor.md) — Залежність: PaymentConductor використовує курси Oracle, коли рейка перетинає номінали.

  
- [features/store](/docs/features/store.md) — Той самий процес: display каталогу, presentment checkout і серверне створення charge.

  
- [features/wallet](/docs/features/wallet.md) — Поглиблення: котирування Token Desk, облік кредитів і баланси native token.
