ServicesMoniker

Premium Names and Escrow

Two features that both settle through Treasury: a namespace can charge for names that match a pattern, and a transfer between two owners can hold the buyer's funds until the seller signs off. Neither is on by default - a plain namespace never touches Treasury at all.

Both use the namespace_id as the Treasury domain and auto-create the currency and wallets they need on first use.

Pricing patterns

Set premium on the namespace. Patterns are evaluated in order and the first match wins:

{
  "name": "shops",
  "premium": {
    "enabled": true,
    "treasury_account": "shop-name-treasury",
    "patterns": [
      { "rule": "max_length", "value": 6, "price": { "currency": "GOLD", "amount": 500 } },
      { "rule": "dictionary_word",       "price": { "currency": "GOLD", "amount": 5000 } },
      { "rule": "regex", "pattern": "^x", "price": { "currency": "GOLD", "amount": 250 } }
    ]
  }
}
  • max_length matches names up to value characters - the classic short-name premium.
  • dictionary_word matches an exact canonical word from a small built-in list (dragon, phoenix, knight, wizard, shadow, storm, flame, frost, king, queen, gold). It is exact, not stemmed: Dragon priced, Dragons did not.
  • regex matches the pattern against the canonical form.

Quote at reserve, charge at confirm

reserve prices the name and tells you before anyone commits:

snug moniker reserve --namespace shops --name Anvil
{
  "reservation_id": "name_77d64415a1154d359930b81fa43e85ce",
  "name": "Anvil", "canonical": "anvil", "status": "reserved",
  "expires_at": "2026-08-28T23:12:16.502832Z",
  "premium": true,
  "price": { "amount": 500, "currency": "GOLD" }
}

confirm is where money moves: it debits the caller's wallet in that currency and credits the namespace's treasury_account, then flips the name to active. The name's history records both:

reserved
premium_paid   | paid 500 GOLD
confirmed      | premium acquisition

No payment, no name. An unfunded buyer gets 402 payment_required and the reservation stays reserved with its deadline restored, so you can fund the wallet and retry the same reservation_id. Nothing is half-registered. A namespace with premium.enabled but no treasury_account fails the same way, with 400 treasury_account_missing.

On this path the 402 message currently reports the price as 0 ("wallet wal_... has 0, premium name costs 0") - read the real price from the reserve response, not from the error text. The escrow-open 402 reports it correctly.

Escrowed transfers

Add --escrow to a transfer and ownership does not move yet:

snug moniker transfer --namespace shops --name Anvil --to docs4-other --escrow
{ "name": "Anvil", "status": "active",
  "owner": { "type": "user", "id": "docs-wave" },
  "escrow_pending": true,
  "escrow_id": "esc_410ce76452cf4f74b0eaf332ce3f87ea" }

Opening the escrow places a Treasury hold on the buyer's wallet for the name's premium price, an 800 GOLD buyer wallet went to balance 800, held 500, available 300. A name with no premium price opens a zero-amount escrow with no hold at all, which is a useful way to get the two-step handshake without the money.

snug moniker escrow get    --namespace shops --escrow-id esc_410ce764...
snug moniker escrow settle --namespace shops --escrow-id esc_410ce764...
snug moniker escrow cancel --namespace shops --escrow-id esc_410ce764...
  • Settle captures the hold and flips ownership to the buyer, appending both escrow_settled and transferred to the name's history. Only the seller (or a platform admin) may settle - the buyer gets 403 insufficient_permissions.
  • Cancel releases the hold and leaves ownership with the seller. Either party may cancel.
  • Either way the escrow becomes terminal: a second settle or cancel is 409 escrow_not_open, and escrow get still returns the record with its status and closed_at.

Captured funds are credited to the namespace's configured treasury_account, not to the selling user's own wallet. If you are running a peer-to-peer name market, pay sellers out of that account yourself.

Gotchas

  • An open escrow freezes the name. A second escrowed transfer and a release both fail with 409 escrow_already_open until the escrow settles or cancels.
  • The buyer needs funds at escrow-open time, not at settle time. The hold is placed when the transfer opens, so an underfunded buyer fails there with 402 payment_required and no escrow is created.
  • Currency and wallets are created on demand in the namespace's domain, with a zero balance and overdraft denied. Fund the buyer before the first premium confirm or escrowed transfer, or it will fail with 402.
  • Pattern order is the price list. A short dictionary word matches whichever rule you listed first, so put the expensive rules on top.

Reference

On this page