---
title: "WalletConductor"
description: "Єдиний фасад SSOT для кастодіальних гаманців із нативним токеном, фіатного кредитного реєстру, Token Desk, поповнення карткою, конфіденційного native onramp і покупок на NFT-маркетплейсі — грошовий аналог PaymentConductor"
locale: "uk"
---
# WalletConductor

**WalletConductor** — це фасад оркестрації Ring Platform для грошових шляхів **кастодіального native-token web3** і **фіатного кредиту**. Тонкі адаптери (`app/_actions/wallet.ts`, `/api/wallet/token/*`, `/api/wallet/desk/*`, покупка на NFT-маркетплейсі) викликають conductor; він делегує PSP до [PaymentConductor](/docs/features/payment-conductor.md), а обчислення реєстру — до `creditBalanceService`.

> **Info**
> Використовуйте вкладки **Founder** / **Developer** на бічній панелі документації, щоб відфільтрувати цю сторінку. Користувацький UI продукту: [Wallet](/docs/features/wallet.md). Реєстр HTTP/actions: [Wallet API](/docs/api/wallet.md).

Один шар для грошових операцій гаманця: картка → **кредитні бали**, desk → **native token**, кастодіальні gasless-відправлення, довільне списання кредиту та покупки на NFT-маркетплейсі. Облік фіатних витрат використовує `credit.creditBalanceUnitToMainCurrency` (зазвичай `1`) — ніколи не oracle desk. Зовнішні EVM POL/USDT через `POST /api/wallet/transfer` залишаються **поза** цим conductor.

```mermaid
flowchart TB
  subgraph surfaces["Surfaces"]
    SA["Server Actions\\napp/_actions/wallet.ts"]
    API["HTTP /api/wallet/*"]
    NFT["NFT market buy"]
    OAuth["OAuth / ensure"]
  end

  subgraph WC["WalletConductor"]
    TOP["initiateTopUp"]
    ONR["initiateNativeOnramp"]
    DESK["quoteDesk / executeDesk"]
    SEND["transferNative"]
    SPEND["spendCredits"]
    ENS["ensureNativeWallet"]
    NFTB["purchaseNftListing"]
  end

  subgraph deps["Dependencies"]
    PC["PaymentConductor\\nwallet_topup / native_token_onramp"]
    CBS["creditBalanceService"]
    DS["desk-service + native-token-oracle"]
    XFER["native-token-transfer-service"]
    EW["ensure-wallet"]
    SOL["SolanaMarketClient"]
  end

  SA --> WC
  API --> WC
  NFT --> NFTB
  OAuth --> ENS
  TOP --> PC
  ONR --> PC
  DESK --> DS
  SPEND --> CBS
  SEND --> XFER
  ENS --> EW
  NFTB --> SOL
  DS --> CBS
```

## За що відповідає WalletConductor

| Можливість | Метод | Результат |
|------------|--------|--------|
| **Картка → кредитні бали** | `initiateTopUp` | PaymentConductor `wallet_topup` → кредит фіатного реєстру |
| **Картка/PayPal → treasury native** | `initiateNativeOnramp` | PaymentConductor `native_token_onramp` (confidential+) |
| **Token Desk** | `quoteDesk` / `executeDesk` | Кредитні бали ↔ native за oracle desk (subscriber+) |
| **Кастодіальне відправлення** | `transferNative` | Gasless-переказ native + рядок у `wallet_transactions` |
| **Native-баланс** | `getNativeBalance` | Кастодіальний баланс native chain платформи |
| **Довільне списання кредиту** | `spendCredits` | Дебет фіатного реєстру за `creditBalanceUnitToMainCurrency` |
| **Створення гаманця** | `ensureNativeWallet` | Атомарні мультичейн-гаманці (безпечні для OAuth, без сесії) |
| **Мінімальний кредитний поріг** | `ensureFunded` | Створення із сесією + мінімальний кредитний залишок |
| **Покупка на NFT-маркетплейсі** | `purchaseNftListing` | Ідемпотентна покупка RING через Solana market client |

**Не входить до WalletConductor:** дебет checkout магазину/членства (PaymentConductor `credit_balance` / SubscriptionConductor) і зовнішній EVM `POST /api/wallet/transfer`. Це навмисно окремі шляхи SSOT.

## Дві ставки — не змішуйте їх

| Ставка | SSOT | Використовують |
|------|------|---------|
| **Облік фіатного кредиту** | `ring-config.json` → `credit.creditBalanceUnitToMainCurrency` (зазвичай `1`) через `getMainCurrencyCreditAccountingRate()` | `spendCredits`, дебетова сторона desk, checkout `credit_balance` |
| **Oracle Token Desk** | `platform_settings.web3.oracle.nativePerMainCurrency` через `native-token-oracle.ts` | Лише бали ↔ native у `quoteDesk` / `executeDesk` |

### For founders

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

WalletConductor — грошовий хребет для оператора за продуктом [Wallet](/docs/features/wallet.md). Учасники бачать UI поповнення, desk і відправлення; ваш клон залишається узгодженим, бо кожен шлях проходить через один фасад, а не через розрізнені виклики PSP і реєстру.

  
- **[Поповнення кредиту](/docs/features/wallet.md)** — Будь-який авторизований учасник купує кредитні бали карткою. Бали — це одиниці фіатного реєстру (1:1 з `mainCurrency` магазину, коли `creditBalanceUnitToMainCurrency` дорівнює `1`).

  
- **[Token Desk](/docs/features/wallet.md)** — Учасник із рівнем Subscriber+ конвертує бали ↔ native за oracle desk. Зміна `nativePerMainCurrency` ніколи не переписує математику checkout магазину чи довільного списання кредиту.

  
- **[Native onramp](/docs/features/payment-conductor.md)** — Confidential+ картка/PayPal → treasury native (під керуванням feature flag). Кредитні бали **не** додаються.

  
- **[Покупка на NFT-маркетплейсі](/docs/features/nft-market.md)** — Допущені покупці сплачують RING із кастодіального гаманця через `purchaseNftListing` (ідемпотентний рядок продажу).

### Чекліст оператора

**Підтвердьте SSOT одиниці кредиту**

Залишайте `credit.creditBalanceUnitToMainCurrency: 1` у `ring-config.json`, якщо навмисно не масштабуєте бали відносно фіату. Зміни oracle desk не впливають на checkout магазину або `POST /api/wallet/credit/spend`.

**Відокремлюйте oracle desk від фіату**

Superadmin налаштовує `nativePerMainCurrency` лише для конвертації desk. Не очікуйте, що ця ставка буде використана для довільного списання кредиту.

**Обережно вмикайте native onramp**

Native onramp карткою доступний для confidential+ і керується feature flag (`CONFIDENTIAL_TOKEN_ONRAMP` / desk `nativeTokenOnramp`). Не вмикайте його, доки treasury ops і compliance не готові.

> **Tip**
> Надавайте перевагу Server Actions з UI. Залишайте HTTP wallet routes для MCP і клієнтів без React. Надавайте перевагу `/api/wallet/token/*` — застарілі aliases `/api/wallet/ring/*` видалені.

### For developers

## Реалізація

Фасад: `features/wallet/conductor/wallet-conductor.ts` (`server-only`).

{`import { WalletConductor } from '@/features/wallet/conductor/wallet-conductor'

// OAuth / events — no session required
const ensured = await WalletConductor.ensureNativeWallet({ id: userId, role })

// Card → credit points (amount 25–2000)
const topUp = await WalletConductor.initiateTopUp(null, formData)

// Ad-hoc fiat debit — rate defaults to creditBalanceUnitToMainCurrency
const spent = await WalletConductor.spendCredits({
  userId,
  amount: '10.00',
  description: 'API debit',
})

// Desk (subscriber+)
const quote = await WalletConductor.quoteDesk({ userId, role, side: 'buy', amount: '100' })
await WalletConductor.executeDesk({ userId, role, idempotencyKey, quoteToken })`}

### Підключення поверхні

**Викликайте фасад, а не реєстр**

UI і routes мають імпортувати `WalletConductor` (або тонкі обгортки в `app/_actions/wallet.ts`). Не списуйте кошти через `creditBalanceService` з feature UI для шляхів, за які відповідає conductor.

**Зберігайте SSOT фіатної ставки**

Для шляхів витрат опускайте `usdRate` або передавайте `getMainCurrencyCreditAccountingRate()`. Ніколи не підставляйте `nativePerMainCurrency` / oracle desk у дебети фіатного реєстру.

**Дотримуйтеся межі EVM**

Кастодіальне native-відправлення — це `transferNative`. Зовнішній SupportedCrypto (POL/USDT) залишається на `POST /api/wallet/transfer` — не включайте його до WalletConductor без явного redesign.

### Карта модулів

| Рівень | Шлях |
|-------|------|
| Фасад | `features/wallet/conductor/wallet-conductor.ts` |
| Створення | `features/wallet/services/ensure-wallet.ts` |
| Кредитний реєстр | `features/wallet/services/credit-balance-service.ts` |
| Фіатна ставка | `lib/ring-config-core.ts` → `getCreditUnitToMainCurrencyRate` / `lib/payments/credit-balance.ts` → `getMainCurrencyCreditAccountingRate` |
| Desk | `features/wallet/chains/solana/desk-service.ts` |
| Oracle desk | `features/wallet/services/native-token-oracle.ts` |
| Кастодіальне відправлення | `features/wallet/chains/native-token-transfer-service.ts` |
| Checkout PSP | `lib/payments/conductor/payment-conductor.ts` |
| Кредитний rail магазину | `lib/payments/processors/credit-balance.processor.ts` (PaymentConductor — не WC) |
| Actions | `app/_actions/wallet.ts` |
| Покупка NFT | `features/nft-market/services/solana-market-client.ts` |

### Контракти методів

| Метод | Auth / gates | Примітки |
|--------|--------------|-------|
| `ensureNativeWallet` | Caller supplies `id` | Безпечно для OAuth; повертає `{ ok, native, wallets }` |
| `ensureFunded` | Session | Створює + необов’язковий мінімум кредиту |
| `initiateTopUp` | Session | Сума 25–2000; purpose `wallet_topup` |
| `initiateNativeOnramp` | Session + confidential metadata | Необов’язковий `processor` paypal/stripe/wayforpay |
| `quoteDesk` / `executeDesk` | `assertTokenDeskSubscriberAccess` | SSOT Solana desk |
| `transferNative` | Caller supplies `userId` | Записує `wallet_transactions`; працює з контактами |
| `spendCredits` | Caller supplies `userId` | Типово використовує `getMainCurrencyCreditAccountingRate()` для `usdRate` |
| `purchaseNftListing` | Idempotency key | Статуси: pending → submitted → confirmed / failed |
| `getNativeBalance` | Caller supplies `userId` | Тонка обгортка transfer service |

### Послідовність — поповнення кредиту карткою

```mermaid
sequenceDiagram
  participant UI as CreditAddFsModal
  participant WC as WalletConductor
  participant PC as PaymentConductor
  participant PSP as WayForPay_or_Stripe_or_PayPal
  participant WH as wallet_topup_webhook
  participant CBS as creditBalanceService
  UI->>WC: initiateTopUp formData
  WC->>PC: createCheckout purpose=wallet_topup
  PC-->>UI: redirect navigate_or_form_post
  UI->>PSP: followCheckoutResult
  Note over UI,PSP: returnUrl browser UX only
  PSP->>WH: webhook Approved_or_capture
  WH->>CBS: addFiatUsd fiat points
```

У вкладці Card `processor` не передається (SSOT з env). Вкладка PayPal задає `processor=paypal`. Клієнт: `lib/payments/checkout-redirect.ts`.

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

```mermaid
sequenceDiagram
  participant API as POST /api/wallet/credit/spend
  participant WC as WalletConductor.spendCredits
  participant RATE as getMainCurrencyCreditAccountingRate
  participant CBS as creditBalanceService
  API->>WC: amount, description
  WC->>RATE: creditBalanceUnitToMainCurrency
  WC->>CBS: spendCredits(..., usdRate)
  CBS-->>API: newBalance, transactionId
```

### Середовище й конфігурація (перевірено)

| Key | Роль |
|-----|------|
| `WALLET_ENCRYPTION_KEY` | Шифрування кастодіальних ключів |
| `SOLANA_RPC_URL` / `SOLANA_TREASURY_PRIVATE_KEY` | Кастодіальний Solana + спонсорування gas |
| `CONFIDENTIAL_TOKEN_ONRAMP` / desk `nativeTokenOnramp` | Gate native onramp карткою |
| `credit.creditBalanceUnitToMainCurrency` | Множник обліку фіатного реєстру |
| `ORACLE_QUOTE_SECRET` / `RING_ORACLE_DEFAULT_RATE` | HMAC котирування desk + fallback |

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

  
- **[Generative Gallery](/docs/features/generative-media.md)** — Генеративний білінг із пріоритетом кредиту через `spendCredits` + реєстр `generative_usage`.

  
- **[Архітектура WalletConductor](/docs/architecture/wallet-conductor.md)** — Адаптери, карта routes, послідовності, SSOT env.

  
- **[Функція Wallet](/docs/features/wallet.md)** — Архітектура продукту та користувацькі потоки.

  
- **[Wallet API](/docs/api/wallet.md)** — Actions, HTTP routes, таблиці SSOT ставок.

  
- **[PaymentConductor](/docs/features/payment-conductor.md)** — PSP rails, які використовують поповнення й onramp.
