argus/src/web/register-entry.js

60 lines
2.6 KiB
JavaScript
Raw Normal View History

// Browser entry point for the registration flow. Everything the register page
// needs, and nothing that touches the filesystem or a private key we hold.
//
// Bundled by build-web.mjs to site/js/bns-register.js as a plain ES module:
// <script type="module"> import * as BNS from './js/bns-register.js' </script>
export { BuiltInWallet, CHIPNET_PREFIX, MAINNET_PREFIX, DEFAULT_PREFIX } from "../lib/wallet-web.js";
export {
connect,
checkAvailability,
quoteRegistration,
registerWithBuiltInWallet,
registerWithExternalWallet,
registerTldWithBuiltInWallet,
registerTldWithExternalWallet,
feat(registrar): 90/10 revenue split — TLD owner earns from name mints Every second-level name registration under a TLD now routes 90% of the service fee to whoever holds that TLD's certificate on chain, with 10% going to the platform address. That's the economic incentive for minting a TLD: you earn from every name registered under it. The mechanism, end to end: 1. resolver-web.js fetchTldMap now also records mintScriptHex — the scriptPubKey of the TREG output that carries each TLD's NFT. Exported so registrar can decode it into a cashaddr with libauth. MVP: this is the ORIGINAL owner; NFT transfers after mint are not traced yet (a follow-up will walk the chain of transfers). 2. registrar.js gains findTldOwnerAddress(client, tld) and splitServiceFee(sats). The split constants live at the top of the file (TLD_OWNER_SHARE_NUM/DEN = 90/100) so the ratio moves in one place. Rounding: BigInt division favours the platform on odd sat counts so the two shares always sum EXACTLY to the input. 3. quoteRegistration wraps the existing flow: it derives the TLD from the name, looks up the TLD owner, and if the owner ≠ buyer it asks buildRegistrationTx to add a second fee output. If the owner couldn't be resolved (TLD not registered, decode failure) the full fee stays on the platform address — the buyer still pays the same amount either way. 4. register-tx.js buildRegistrationTx accepts tldFeeAddress/tldFeeSats and, when set, emits an extra P2PKH output for the TLD owner. Sits between the beacon dust and the platform-fee output; outputMap records .tldOwnerFee so callers can find it. costs also carries tldOwnerFeeSats and netCostSats includes it. 5. priceSummary in registrar-config splits the 'Service fee' row into 'Service fee — TLD owner (90%)' + 'Service fee — platform (10%)' whenever tldOwnerFeeSats > 0, with a per-line note explaining where the money goes. Bundle: re-exported findTldOwnerAddress + splitServiceFee from register-entry.js. Rebuilt bns-register.js (~34 kB) and deployed; cache-buster bumped to ?v=20260908split on portal / admin / register-flow.js. Verified live: findTldOwnerAddress('.bch') returns the operator cashaddr; quoteRegistration('tester42.bch') builds cleanly with a 9,000/1,000 split output pair on a 10,000-sat fee; priceSummary renders both lines. No regressions on the TLD-mint flow (buyer IS the TLD owner there — split short-circuits and it stays a single fee output as before).
2026-09-08 02:42:16 +02:00
findTldOwnerAddress,
splitServiceFee,
setRecordsWithBuiltInWallet,
setRecordsWithExternalWallet,
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
setTldRecordsWithBuiltInWallet,
signRecordsManifest,
findCertificateUtxo,
getBalance,
} from "../lib/registrar.js";
export { REGISTRAR, priceSummary } from "../registrar-config.js";
export {
buildRegistrationTx,
buildTldRegistrationTx,
buildUpdateTx,
buildPrepTx,
hasGenesisInput,
toWcTransactionObject,
normalizeName,
normalizeTld,
displayName,
payloadBudget,
TLD_BEACON,
NoGenesisInputError,
InsufficientFundsError,
} from "../lib/register-tx.js";
export { signTransaction, txidOf, txidOfHex } from "../lib/sign-tx.js";
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
export { buildListing, completeSale, verifyListing, signInputs, sourceOutputToJson, sourceOutputFromJson } from "../lib/market-tx.js";
export { findTldCertificateUtxo, buildCosignRequest, signCosignRequest } from "../lib/registrar.js";
feat(market): names can be priced in US dollars — a covenant holds the certificate, a gateway-signed oracle sets the BCH amount A BCH-priced offer is a signed transaction with a fixed amount, so a seller who wants "$500" had to relist whenever the rate moved. The new USD mode moves the certificate into a small CashScript covenant (contracts/usd-listing.cash). Anyone may buy it by paying the seller target_cents / price, where the price comes from a message signed by the gateway's oracle key — the median of five exchanges the site already uses. The payout is clamped to a floor/ceiling band the seller sets, and the seller can reclaim the certificate at any time. What the chain can and cannot enforce, stated plainly in the contract and the UI: script can require a transaction to be mined no earlier than a time, never no later, so a quote cannot expire on-chain. The band is the guarantee, and quotes are bound to the listing's outpoint so cancelling and relisting voids every quote ever issued. An offline libauth VM test covers list, buy, underpayment, foreign-listing quotes, forged quotes, band clamping, cancel and a non-seller cancel; on chipnet aloevera.test was listed at $0.30, bought by a second wallet for 119,090 sat at $251.91, listed again by the new owner and cancelled. Gateway: GET /api/price/oracle[?txid=] serves the oracle public key and per-listing signed quotes; the key lives in oracle.key beside the gateway, never in the repo. POST /api/market accepts kind "usd" after reproducing the redeem script from the stated terms and finding the certificate in that covenant; such listings are pruned once the covenant output is spent; DELETE accepts the listing's seller while the index shows the covenant as holder. Dashboard: the Sell tab has "Price is fixed in: US dollars / BCH", a band control with the resulting BCH range, and cancel through the covenant. Market: USD listings show the dollar price, today's BCH equivalent and the band; buying fetches a quote and completes the covenant spend. Studio no longer sends a needless UPD when the registry view is stale, and missing files on a name now get a real 404 page.
2026-09-20 19:20:46 +02:00
export { usdListingRedeem, usdListingAddress, payoutSats, parseOracleMessage, verifyOracleMessage, buildUsdListingTx, buildUsdBuyTx, buildUsdCancelTx, verifyUsdListing, DEFAULT_MAX_AGE_SECS } from "../lib/market-usd.js";
sirius.x portal: /api/holdings endpoint + favicon paths + roadmap link gateway/public-gateway.mjs: * GET /api/holdings/<scripthash> and POST /api/holdings {scripthashes:[…]} — server-side wallet-holdings lookup for the portal. Bns-indexer is beacon-only so it can't answer listunspent for arbitrary addresses; the gateway does the electrum roundtrip and cross-joins with the cached BCNR index. Client posts scripthashes (no libauth needed on the server) and gets back the names owned. * elConnect now falls through to whole-buffer JSON.parse when a Fulcrum response lacks a trailing newline — chipnet.bch.ninja does this and otherwise every elCall to it times out. Same tolerance pattern as bns-indexer.test.mjs's tiny electrum client. * verifyElectrum picks a full electrum with a 3s server.version probe so a hung server fails over to the next in seconds instead of stalling 20. * Skips silentmode.st/electrum and coinspectrum.duckdns.org:50011 for /api/holdings — both are bns-indexer routes that don't do listunspent. web/register-entry.js: export addressToScripthash so the portal can derive the scripthash for each of its wallet's watched addresses before POSTing. Browser bundle rebuilt. site-sirius-x pages: * favicon + logo hrefs made relative (./assets/… on index/portal, ../assets/… on docs/theseus). Absolute /sirius-x/… broke on the sirius.x BCNR route where the site is served from root instead of under /sirius-x/. * Roadmap nav link added back to portal, docs, theseus — the landing has an anchor to a section on itself, so subpages now link to it explicitly. * portal.html: loadNames rewritten to POST scripthashes to /api/holdings instead of doing client-side electrum. Works on browsers whose networks block chipnet electrum ports; same-origin HTTPS on 443. * portal.html: bundle import ?v= bumped so Chrome's in-memory ES module map picks up the new bundle instead of a stale cached copy.
2026-08-31 05:40:47 +02:00
export { toTokenAddress, addressToLockingBytecode, addressToScripthash, getUtxos, getUtxosForAddresses, broadcast } from "../lib/chain.js";
export { resolveName, buildIndex, NETWORK, NETWORKS, getNetwork, requireBeacons, DEFAULT_NETWORK_ID } from "../lib/resolver-web.js";
export {
describeGenesisRequirement,
pubkeyToAddress,
pubkeyToLockingBytecode,
} from "../lib/connect/wallet-session.js";
export { binToHex, hexToBin } from "@bitauth/libauth";
export { stringify } from "@bitauth/libauth";
// NOT re-exported here on purpose: the WizardConnect and WalletConnect adapters.
// They are separate bundles (site/js/wizardconnect.js, site/js/walletconnect2.js)
// that the page dynamic-imports only when the buyer picks that option.
// - WizardConnect: LGPL-3.0-or-later, must stay separate + unminified (§4d1).
// - WalletConnect: ~590 kB nobody using the built-in wallet should download.