---
title: "billing.wallet@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/billing.wallet"
updated: null
---

# billing.wallet@1 · OpenVibe.Services

HTML: [billing.wallet@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/billing.wallet)

# BillingWallet `billing.wallet@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: billing
- Visibility: public
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/billing/wallet.v1.json`](/docs/contracts/billing.wallet.json)

Universal wallet: billing.wallet. Personal bearer reads and purchases; server-side reviewed prices.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `subject` | object | yes |  | - `no other fields` |
| `subject.type` | const | yes |  | - `= "user"` |
| `subject.id` | string | yes |  | - `pattern ^usr_[0-9A-HJKMNP-TV-Z]{26}$` |
| `currency` | const | yes |  | - `= "USD"` |
| `money_writes_frozen` | boolean | yes |  |  |
| `used_ai_this_month` | boolean | yes |  |  |
| `balances` | object | yes |  | - `no other fields` |
| `balances.coins` | object | yes |  | - `no other fields` |
| `balances.coins.label` | string | yes |  |  |
| `balances.coins.amount` | string | yes |  | - `pattern ^[0-9]+$` |
| `balances.coins.currency` | enum | yes |  | - `one of "opencoins", "vibes-bits", "USD"` |
| `balances.coins.scale` | enum | yes |  | - `one of 0, 9` |
| `balances.coins.purpose` | string | yes |  |  |
| `balances.coins.action` | string | yes |  |  |
| `balances.coins.held` | string |  |  | - `pattern ^[0-9]+$` |
| `balances.vibes` | object | yes |  | - `no other fields` |
| `balances.vibes.label` | string | yes |  |  |
| `balances.vibes.amount` | string | yes |  | - `pattern ^[0-9]+$` |
| `balances.vibes.currency` | enum | yes |  | - `one of "opencoins", "vibes-bits", "USD"` |
| `balances.vibes.scale` | enum | yes |  | - `one of 0, 9` |
| `balances.vibes.purpose` | string | yes |  |  |
| `balances.vibes.action` | string | yes |  |  |
| `balances.vibes.held` | string |  |  | - `pattern ^[0-9]+$` |
| `balances.balance` | object | yes |  | - `no other fields` |
| `balances.balance.label` | string | yes |  |  |
| `balances.balance.amount` | string | yes |  | - `pattern ^[0-9]+$` |
| `balances.balance.currency` | enum | yes |  | - `one of "opencoins", "vibes-bits", "USD"` |
| `balances.balance.scale` | enum | yes |  | - `one of 0, 9` |
| `balances.balance.purpose` | string | yes |  |  |
| `balances.balance.action` | string | yes |  |  |
| `balances.balance.held` | string |  |  | - `pattern ^[0-9]+$` |
| `bits_per_usd` | number | yes |  |  |
| `recent_activity` | array of object | yes |  | - `maxItems 5`<br>- `items: no other fields` |
| `recent_activity[].id` | string | yes |  |  |
| `recent_activity[].at` | string | yes |  | - `format date-time` |
| `recent_activity[].kind` | enum | yes |  | - `one of "coins", "vibes", "balance"` |
| `recent_activity[].amount` | string | yes |  | - `pattern ^-?[0-9]+$` |
| `recent_activity[].label` | string | yes |  |  |
| `recent_activity[].detail` | string | yes |  |  |
| `recent_activity[].site` | string | yes |  |  |
| `checkout` | object | yes |  | - `no other fields` |
| `checkout.providers` | array of object | yes | The checkout providers on offer, each with the hosts its hosted checkout may use. The wallet follows a checkout\_url only to one of these hosts or to Billing itself. | - `items: no other fields` |
| `checkout.providers[].name` | string | yes |  | - `minLength 1`<br>- `maxLength 40` |
| `checkout.providers[].hosts` | array of string | yes |  | - `items: minLength 1`<br>- `items: maxLength 253` |
| `checkout.vibes` | object | yes |  | - `no other fields` |
| `checkout.vibes.minimum` | integer | yes |  | - `minimum 1` |
| `checkout.vibes.maximum` | integer | yes |  | - `minimum 1` |
| `checkout.vibes.price_tiers` | array of object | yes |  | - `items: no other fields` |
| `checkout.vibes.price_tiers[].min` | integer | yes |  | - `minimum 0` |
| `checkout.vibes.price_tiers[].usd_per_bit` | number | yes |  |  |
| `checkout.topup` | object | yes |  | - `no other fields` |
| `checkout.topup.enabled` | boolean | yes |  |  |
| `checkout.topup.amounts_cents` | array of integer | yes |  | - `items: minimum 1` |
| `checkout.topup.fee_bps` | integer \| null | yes |  | - `minimum 0`<br>- `maximum 10000` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: example

~~~~
{
  "subject": {
    "type": "user",
    "id": "usr_00000000000000000000000001"
  },
  "currency": "USD",
  "money_writes_frozen": false,
  "used_ai_this_month": true,
  "balances": {
    "coins": {
      "label": "OpenCoins",
      "amount": "0",
      "currency": "opencoins",
      "scale": 0,
      "purpose": "Earned by taking part",
      "action": "How to earn OpenCoins"
    },
    "vibes": {
      "label": "Vibes",
      "amount": "0",
      "currency": "vibes-bits",
      "scale": 0,
      "purpose": "Support creators and buy items",
      "action": "Buy Vibes"
    },
    "balance": {
      "label": "Balance",
      "amount": "0",
      "currency": "USD",
      "scale": 9,
      "purpose": "AI and paid features",
      "action": "Top up"
    }
  },
  "bits_per_usd": 100,
  "recent_activity": [],
  "checkout": {
    "providers": [
      {
        "name": "stripe",
        "hosts": [
          "checkout.stripe.com"
        ]
      }
    ],
    "vibes": {
      "minimum": 100,
      "maximum": 100000,
      "price_tiers": [
        {
          "min": 100,
          "usd_per_bit": 0.012
        }
      ]
    },
    "topup": {
      "enabled": true,
      "amounts_cents": [
        1000
      ],
      "fee_bps": 0
    }
  }
}
~~~~

Rejected: invalid-value

~~~~
{
  "subject": {
    "type": "user",
    "id": "usr_00000000000000000000000001"
  },
  "currency": "USD",
  "money_writes_frozen": false,
  "used_ai_this_month": true,
  "balances": {},
  "bits_per_usd": 100,
  "recent_activity": [],
  "checkout": {
    "providers": [
      "stripe"
    ],
    "vibes": {
      "minimum": 100,
      "maximum": 100000,
      "price_tiers": [
        {
          "min": 100,
          "usd_per_bit": 0.012
        }
      ]
    },
    "topup": {
      "enabled": true,
      "amounts_cents": [
        1000
      ],
      "fee_bps": 0
    }
  }
}
~~~~

Rejected: missing

~~~~
{}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('billing.wallet@1', value);   // { valid, errors: [{ path, message }] }
~~~~
