sirius/js/pricing.js

231 lines
9.9 KiB
JavaScript
Raw Normal View History

feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
// Sirius.X pricing model — deterministic per-label cost so users can predict
// what a name or TLD will cost before they click Register. Public tiers only;
// operator-level discounts and coupon overrides land in a future revision
// (the plan is oracle-fed rates + coupon-code redemption at mint time).
//
// Two layers decide what a NAME costs:
// 1. The TLD owner's on-chain policy (`price`, `hidden`, `policy`) — read
// from the gateway's /api/tlds snapshot of the TLD beacon. A TLD owner
// who sets `price: 7` sells every name under that TLD for $7, flat.
// 2. Otherwise the length tiers below.
//
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
// Exposed as window.siriusPricing so both the register-flow modal and the
// inline search widgets on landing/tld.html use one source of truth.
(() => {
// Chipnet placeholder rate: mainnet swaps this for a real BCH/USD oracle.
// The numbers keep the demo transactions in the "few chipnet coins" range
// so a single faucet visit covers a name or a TLD.
const CHIPNET_SATS_PER_USD = 250_000;
const usdToSats = (usd) => BigInt(Math.max(0, Math.round(Number(usd) * CHIPNET_SATS_PER_USD)));
const cleanLabel = (s) => String(s || "").toLowerCase().replace(/[^a-z0-9-]/g, "");
// ---------- TLD owner policies ----------
// tld -> { price, hidden, frozen, policy, owner, records }
// Filled from /api/tlds (see loadTldPolicies). Unknown TLDs fall through
// to tier pricing and are treated as sellable, so a gateway blip never
// blocks a purchase; the chain is the authority at mint time anyway.
// include_hidden=1 so the policy map knows about switched-off (private)
// TLDs too — their owners register names under them from the portal, and
// the register flow must be able to price and gate them. The public
// listing (visibleTlds) still drops anything hidden.
const TLD_API = "https://navigate.st/api/tlds?include_hidden=1";
const TLD_POLICIES = new Map();
let tldList = null; // raw /api/tlds rows, once loaded (hidden ones excluded)
let tldLoad = null; // memoised in-flight fetch
function normalisePolicy(row) {
const rec = row && row.records && typeof row.records === "object" ? row.records : {};
const priceRaw = row && row.price_usd != null ? row.price_usd : rec.price;
const price = typeof priceRaw === "number" && Number.isFinite(priceRaw) && priceRaw >= 0 ? priceRaw : null;
const hidden = !!(row && row.hidden) || rec.hidden === 1 || rec.hidden === true;
const policy = typeof rec.policy === "string" ? rec.policy : "open";
return {
tld: row.tld,
price,
hidden,
hiddenBy: row && row.hidden_by ? row.hidden_by : (hidden ? "owner" : null),
frozen: policy === "frozen",
feat(bns): name marketplace and TLD-owner co-sign rule Two gaps the owner panel left open. First, a hidden TLD was only a UI gate: anyone could still broadcast a REG under it and every indexer admitted it. Second, there was no way to sell a name without trusting the other side. Co-sign rule (consensus, applied in lockstep by bns.js and resolver-web.js): a REG under a TLD whose records at that height say policy "cosign" or hidden 1 is indexed only if the transaction carries the TLD's own certificate. The certificate can only be spent by the owner's key and is re-issued to them in the same transaction, so it is a co-signature nobody can forge and nothing is consumed. The TLD map now keeps the TUPD timeline so policy is evaluated at the REG height. Owners register under their private TLDs with the certificate added from their own wallet; third parties under a "cosign" TLD build the full transaction, sign their inputs and queue it at /api/cosign, where the owner approves it from the dashboard (signCosignRequest refuses to sign unless the certificate returns to the same locking script). Marketplace: a listing is the seller's certificate input plus a price output signed SIGHASH_SINGLE|ANYONECANPAY, stored by the gateway as a bulletin board (/api/market, verified against the on-chain owner and pruned when the certificate moves). The buyer completes it in one transaction, so the seller is paid exactly when the name moves. Cancelling also spends the certificate once so the offer is void. Site: market.html, Sell sub-tab and Pending approvals in the portal, Market link in nav and footer, six dictionaries extended, cache tags bumped. Verified on chipnet: cosigned.sc registered by a throwaway wallet through the queue with the .sc certificate back at the owner; aloevera.test listed and delisted through the API. Ariadne's resolver-web.js copy and the mobile Bns.java port still need the co-sign rule; until then they admit REGs this index rejects.
2026-09-17 04:04:22 +02:00
// cosign: anyone may register, but the TLD owner must co-sign the
// registration (indexers reject a REG under a cosign/hidden TLD that
// does not carry the TLD certificate). hidden implies the same rule
// on chain; in the UI hidden is owner-only, cosign is request-based.
cosign: policy === "cosign",
policy,
feat(bns): name marketplace and TLD-owner co-sign rule Two gaps the owner panel left open. First, a hidden TLD was only a UI gate: anyone could still broadcast a REG under it and every indexer admitted it. Second, there was no way to sell a name without trusting the other side. Co-sign rule (consensus, applied in lockstep by bns.js and resolver-web.js): a REG under a TLD whose records at that height say policy "cosign" or hidden 1 is indexed only if the transaction carries the TLD's own certificate. The certificate can only be spent by the owner's key and is re-issued to them in the same transaction, so it is a co-signature nobody can forge and nothing is consumed. The TLD map now keeps the TUPD timeline so policy is evaluated at the REG height. Owners register under their private TLDs with the certificate added from their own wallet; third parties under a "cosign" TLD build the full transaction, sign their inputs and queue it at /api/cosign, where the owner approves it from the dashboard (signCosignRequest refuses to sign unless the certificate returns to the same locking script). Marketplace: a listing is the seller's certificate input plus a price output signed SIGHASH_SINGLE|ANYONECANPAY, stored by the gateway as a bulletin board (/api/market, verified against the on-chain owner and pruned when the certificate moves). The buyer completes it in one transaction, so the seller is paid exactly when the name moves. Cancelling also spends the certificate once so the offer is void. Site: market.html, Sell sub-tab and Pending approvals in the portal, Market link in nav and footer, six dictionaries extended, cache tags bumped. Verified on chipnet: cosigned.sc registered by a throwaway wallet through the queue with the .sc certificate back at the owner; aloevera.test listed and delisted through the API. Ariadne's resolver-web.js copy and the mobile Bns.java port still need the co-sign rule; until then they admit REGs this index rejects.
2026-09-17 04:04:22 +02:00
category: row && row.category ? row.category : null,
owner: row && row.owner ? row.owner : null,
records: rec,
};
}
function setTldPolicies(rows) {
TLD_POLICIES.clear();
for (const r of rows || []) {
const row = typeof r === "string" ? { tld: r } : r;
const tld = cleanLabel(row && row.tld);
if (!tld) continue;
TLD_POLICIES.set(tld, normalisePolicy({ ...row, tld }));
}
}
// Fetch the TLD list once per page. Resolves to the array of visible TLD
// rows (or null on failure) — never rejects, callers just fall back.
function loadTldPolicies({ url = TLD_API, force = false } = {}) {
if (tldLoad && !force) return tldLoad;
tldLoad = (async () => {
try {
const r = await fetch(url, { cache: "no-store" });
if (!r.ok) throw new Error("api " + r.status);
const j = await r.json();
const rows = Array.isArray(j.tlds) ? j.tlds : [];
setTldPolicies(rows);
// Only a beacon-sourced list is a sellable list. A gateway still
// serving the legacy `tlds.bch`-derived union includes every suffix
// that ever appeared on a name (".de", ".silentmode", …), which is
// not what the registry sells — keep the page's own fallback then.
tldList = j.source === "TLD_BEACON" ? rows.filter((t) => !t.hidden) : null;
return tldList;
} catch {
return null;
}
})();
return tldLoad;
}
// Resolves once the list is loaded, or after `ms` — search UIs await this
// so the first paint already shows owner prices without ever hanging.
function tldReady(ms = 2500) {
return Promise.race([
loadTldPolicies(),
new Promise((res) => setTimeout(() => res(null), ms)),
]);
}
function tldPolicy(tld) {
return TLD_POLICIES.get(cleanLabel(tld)) || null;
}
// Does one of `addresses` (the signed-in wallet's) hold this TLD's NFT?
// `owner` comes from the gateway's beacon snapshot (mint output, updated
// on every TUPD carrier), so a wallet that owns the TLD matches here.
function isTldOwner(tld, addresses) {
const p = tldPolicy(tld);
if (!p || !p.owner || !addresses) return false;
const list = Array.isArray(addresses) ? addresses : [addresses];
return list.some((a) => typeof a === "string" && a === p.owner);
}
// Can names be sold under this TLD right now?
// hidden → owner switched the TLD off: private TLD. The public cannot
// buy, but the OWNER still can — pass their wallet addresses
// and a hidden TLD they hold answers ok with owner: true.
// frozen → owner set policy "frozen" (no new registrations, owner included)
function tldSellable(tld, addresses) {
const p = tldPolicy(tld);
if (!p) return { ok: true, reason: null, owner: false };
const owner = isTldOwner(tld, addresses);
if (p.frozen) return { ok: false, reason: "frozen", policy: p, owner };
if (p.hidden && !owner) return { ok: false, reason: "hidden", policy: p, owner };
feat(bns): name marketplace and TLD-owner co-sign rule Two gaps the owner panel left open. First, a hidden TLD was only a UI gate: anyone could still broadcast a REG under it and every indexer admitted it. Second, there was no way to sell a name without trusting the other side. Co-sign rule (consensus, applied in lockstep by bns.js and resolver-web.js): a REG under a TLD whose records at that height say policy "cosign" or hidden 1 is indexed only if the transaction carries the TLD's own certificate. The certificate can only be spent by the owner's key and is re-issued to them in the same transaction, so it is a co-signature nobody can forge and nothing is consumed. The TLD map now keeps the TUPD timeline so policy is evaluated at the REG height. Owners register under their private TLDs with the certificate added from their own wallet; third parties under a "cosign" TLD build the full transaction, sign their inputs and queue it at /api/cosign, where the owner approves it from the dashboard (signCosignRequest refuses to sign unless the certificate returns to the same locking script). Marketplace: a listing is the seller's certificate input plus a price output signed SIGHASH_SINGLE|ANYONECANPAY, stored by the gateway as a bulletin board (/api/market, verified against the on-chain owner and pruned when the certificate moves). The buyer completes it in one transaction, so the seller is paid exactly when the name moves. Cancelling also spends the certificate once so the offer is void. Site: market.html, Sell sub-tab and Pending approvals in the portal, Market link in nav and footer, six dictionaries extended, cache tags bumped. Verified on chipnet: cosigned.sc registered by a throwaway wallet through the queue with the .sc certificate back at the owner; aloevera.test listed and delisted through the API. Ariadne's resolver-web.js copy and the mobile Bns.java port still need the co-sign rule; until then they admit REGs this index rejects.
2026-09-17 04:04:22 +02:00
// Sellable, but the registration needs the owner's co-signature: the
// flow builds the request and parks it in the gateway's approval queue.
if (p.cosign && !owner) return { ok: true, reason: "cosign", policy: p, owner };
return { ok: true, reason: null, policy: p, owner };
}
// Visible TLD labels in listing order, or null if no beacon-sourced list
// is available (callers keep their own fallback list then).
function visibleTlds() {
return tldList ? tldList.map((t) => t.tld) : null;
}
// ---------- name pricing ----------
// Owner-set flat price first; else LENGTH-first tiers, then downshift for
// "less brandable" shapes (all-digits, hyphenated). Kept as multiplicative
// modifiers so tiers remain the primary story and mods just soften an
// edge case.
function priceForName(label, tld) {
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
const s = cleanLabel(label);
if (!s) return { usd: 0, tier: "invalid" };
const p = tld ? tldPolicy(tld) : null;
if (p && p.price != null) {
return { usd: p.price, tier: "tld-set", sats: usdToSats(p.price), tld: p.tld, ownerSet: true };
}
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
let usd, tier;
if (s.length === 1) { usd = 5.00; tier = "premium-1"; }
else if (s.length === 2) { usd = 3.00; tier = "short-2"; }
else if (s.length === 3) { usd = 2.00; tier = "short-3"; }
else if (s.length <= 5) { usd = 1.00; tier = "standard"; }
else if (s.length <= 7) { usd = 0.50; tier = "long"; }
else if (s.length <= 16) { usd = 0.25; tier = "extended"; }
else { usd = 0.10; tier = "very-long"; }
// Modifiers.
if (/^\d+$/.test(s)) { usd = round2(usd * 0.5); tier += "+digits"; }
if (s.includes("-")) { usd = round2(usd * 0.7); tier += "+hyphen"; }
return { usd, tier, sats: usdToSats(usd) };
}
// Per-label overrides — TLDs the operator wants priced outside the tiers.
// Cheap namespaces (`.test`, `.dev`, `.local`) exist for experimentation,
// school assignments and demo throwaways: length-tier pricing prices them
// like premium TLDs, which isn't the point. Add labels here to opt them
// out of the tier and (optionally) mark them renewal-free.
//
// Shape: label -> { usd, tier, noRenewal? }
const SPECIAL_TLDS = {
"test": { usd: 0.01, tier: "sandbox", noRenewal: true },
};
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
function priceForTld(label) {
const s = cleanLabel(label);
if (!s) return { usd: 0, tier: "invalid" };
if (Object.prototype.hasOwnProperty.call(SPECIAL_TLDS, s)) {
const o = SPECIAL_TLDS[s];
return { usd: o.usd, tier: o.tier, sats: usdToSats(o.usd), noRenewal: !!o.noRenewal };
}
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
let usd, tier;
if (s.length === 1) { usd = 500.00; tier = "premium-1"; }
else if (s.length === 2) { usd = 250.00; tier = "short-2"; }
else if (s.length === 3) { usd = 150.00; tier = "short-3"; }
else if (s.length <= 6) { usd = 100.00; tier = "standard"; }
else if (s.length <= 10) { usd = 50.00; tier = "long"; }
else { usd = 25.00; tier = "extended"; }
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
return { usd, tier, sats: usdToSats(usd) };
}
// Rounded USD → display string. Under $1 shows cents ($0.25); $1 and up
// shows whole dollars ($5) unless there's a fractional part.
function formatUsd(usd) {
const n = Number(usd || 0);
if (n >= 1 && n === Math.floor(n)) return `$${n}`;
return `$${n.toFixed(2)}`;
}
function formatSats(sats) {
return `${BigInt(sats || 0n).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")} sat`;
}
function round2(n) { return Math.round(Number(n) * 100) / 100; }
window.siriusPricing = {
priceForName,
priceForTld,
formatUsd,
formatSats,
usdToSats,
CHIPNET_SATS_PER_USD,
// TLD owner policy layer
loadTldPolicies,
setTldPolicies,
tldReady,
tldPolicy,
tldSellable,
isTldOwner,
visibleTlds,
TLD_API,
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
};
// Warm the policy cache as soon as the script lands; every consumer
// awaits tldReady() before it paints a price.
loadTldPolicies();
feat(sirius-x): tier-based label pricing; badges on search cards + TLD list Single source of truth (js/pricing.js) mirrored on landing, tld.html and the mint flow — same label always shows the same price everywhere. Name tiers (label part): 1 char $5.00 premium-1 2 chars $3.00 short-2 3 chars $2.00 short-3 4–5 chars $1.00 standard 6–7 chars $0.50 long 8–16 chars $0.25 extended 17+ chars $0.10 very-long all-digits ×0.5 (less brandable) contains hyphen ×0.7 TLD tiers (label part): 1 char $10.00 premium-1 2 chars $8.00 short-2 3 chars $6.00 short-3 4–8 chars $5.00 standard 9+ chars $4.00 long Rendering: - Landing #search-results: acid-tinted price badge on each available row; grid grew a fourth column so name + badge + price + button all sit on one line - tld.html search result-card: same price badge next to the Register button on available TLDs - tld.html registered-TLDs table: new 'Mint price' column showing the tier price for every registered TLD, so buyers see the pricing ladder next to concrete examples Mint pipe: - startFlow(name)/startTldFlow(label) resolve the label price via window.siriusPricing (default) but honour opts.serviceFeeSats when the caller passes one — leaves the door open for coupons / operator discounts / oracle overrides in a future revision without reshuffling call sites - The overridden service fee is threaded through quoteRegistration AND registerWithBuiltInWallet/registerWithExternalWallet so the confirm screen and the on-chain output agree Chipnet placeholder rate (250,000 sat/USD) stays in pricing.js; mainnet will swap in a live BCH/USD oracle. Operator-side discounts and coupon codes are the next iteration — deliberately not disclosed in this shipping copy.
2026-09-09 01:09:05 +02:00
})();