Commit graph

10 commits

Author SHA1 Message Date
Local Dev
0296e8fede 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
Local Dev
7d5fd7211b 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:05:45 +02:00
Local Dev
07925321af fix(wallet): message signatures verified only half the time
BuiltInWallet.signMessage read `recovery` from libauth's recoverable
signature, but libauth v3 names it `recoveryId`. The flag byte came out as
0, so verifiers recovered the right key only when the true recovery id
happened to be 1. Signed DNS manifests and Studio uploads failed with
"signature does not match current on-chain NFT owner" and a different
derived address each attempt. Read the right field, fail loudly if it is
missing, rebuild the browser bundle and move every importer to the new
bundle URL. Also lands the registrar's signRecordsManifest that the bundle
already shipped.
2026-09-17 01:40:10 +02:00
Local Dev
16063b554e 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
Local Dev
1cc7f6e828 feat(registrar): registerTldWithExternalWallet + wire into portal
Adds the external-wallet variant of registerTldWithBuiltInWallet so
WizardConnect users can mint TLDs from the sirius.x portal without
first importing a seed. Same transaction shape (TREG payload, TLD-
beacon output, service-fee output) — the wallet approves the mint
(and, if needed, a one-time prep signature to satisfy the vout-0
non-token genesis-input rule) on the user's own device.

Bundle: re-exported from src/web/register-entry.js and rebuilt
(bns-register.js: 33.3 kB, cache-buster bumped to ?v=20260907tldext
on portal.html / register.html / admin/index.html).

Portal: TLD-register submit now dispatches on wallet.source, calling
registerTldWithExternalWallet with wallet.session when the user is
signed in via WC. Removed the WC-disable guard and updated the card
copy to say TLD mints also go through the wallet's signing prompt.

Uses the same landOnChain helper as registerWithExternalWallet, so
wallet-broadcasts (walletBroadcasts:true sessions) and duplicate/
mempool responses are handled identically.
2026-09-07 01:39:16 +02:00
Local Dev
b02a64c1f2 sirius.x: fix electrum listunspent + profile dropdown across all pages
registrar.js: BNS.connect() now filters silentmode.st/electrum and
coinspectrum.duckdns.org:50011 out of the default electrum list. Those
endpoints are our own bns-indexer.js — beacon-only, serves get_history +
transaction.get but NOT listunspent for arbitrary scripthashes. Every
wallet op (getBalance, getUtxos, edit signing) needs listunspent, so
picking a beacon indexer first (which we did for best reachability) broke
every wallet unlock with "-32601 unsupported method: blockchain.
scripthash.listunspent". New `beaconOk: true` opts back in for pure-
resolution paths.

Rebuilt the browser bundle (site/js/bns-register.js) so the fix reaches
portal + admin + register.html + anything else that imports BNS.connect.

site-sirius-x/js/profile-menu.js: a small shared script that transforms
the "🔑 Sign in" nav pill into a dropdown menu on every sirius.x page.
Signed-out shows New wallet / Add wallet / WizardConnect + a link to the
sign-in page. Signed-in (reads localStorage 'siriusProfile') shows the
short address, My names, Admin, Sign out. Included via one <script defer>
tag on each of the 6 pages (landing / portal / admin / docs / theseus /
brand); dropdown CSS is inlined by the script itself so consumers don't
need a matching stylesheet.

Portal.html writing to localStorage.'siriusProfile' after sign-in is a
follow-up so the dropdown reflects state across pages — until then the
menu always shows the onboarding options.
2026-09-06 18:53:17 +02:00
Local Dev
81bc43e581 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
Local Dev
8532711563 electrum: wire wss://silentmode.st/electrum as first-choice (port 443 reachable)
Bns-indexer on VPS was only exposed on port 50011 via nginx, which corporate
firewalls, mobile carriers, and many VPNs block. Added an nginx location on
443 that proxies to the same 127.0.0.1:50010, giving us a browser-friendly
WSS endpoint on the standard HTTPS port.

  * lib/electrum.js CHIPNET_ELECTRUM: wss://silentmode.st/electrum listed
    first (used by registrar.connect() + everything that depends on it).
  * lib/resolver-web.js CHIPNET_ELECTRUM: same, kept in lockstep per the
    "change both together" comment.
  * bns-register.js bundle rebuilt to bake the new list.
  * portal.html imports the bundle with ?v= so Chrome's in-memory ES-module
    map doesn't serve a stale copy across tabs.

Portal now connects successfully; next remaining issue is that
bns-indexer only supports (server.version, get_history, transaction.get) —
`blockchain.scripthash.listunspent` for wallet address queries is not
implemented, so the "list your names" step fails there. Follow-up: add a
GET /api/holdings/<address> to public-gateway.mjs backed by the existing
BCHN electrum access, so the portal can pull holdings over plain HTTP.
2026-08-31 03:35:39 +02:00
Local Dev
493922af3d Theseus: Firefox-style security panel + search-engine picker
- Security popover redesigned to resemble Firefox's site-info panel:
  lock/shield hero, "Connection secure" status, host, plain-language
  subtitle, and a details grid; the overlay view auto-sizes to content.
- Search-engine picker returned to the toolbar with an "Add / edit engines…"
  entry that opens Settings; added Ecosia, Mojeek, Presearch.
- Custom search engines: add (name + URL template with %s) / remove in
  Settings > General; used by address-bar search.
- Address-bar placeholder: "Ask a search engine or enter web address".
2026-07-30 20:58:45 +02:00
Local Dev
038aca8c09 Initial commit — Silent Mode baseline (2026-07-29)
Snapshot of the decentralized-web stack at the point of the resolver+Theseus
rebuild deploy. Includes:

- Argus (BNS engine + resolver daemon + Sia gateway)
- AriadneResolver (Windows Inno installer bundle + Android APK sources +
  Firefox extension)
- TheseusNavigator (Electron browser)
- site/ (silentmode.st content, deployed to Sia at bns/silentmode/)
- design docs, roadmap, protocol spec

Secrets excluded via .gitignore: Argus/sia-s3.json, Argus/wallets.json,
Argus/ca/*.key,*.crt. Build outputs, node_modules, and bundled runtimes
also excluded.

Shipped hashes on dl.silentmode.st at this commit:
  AriadneResolver-Setup-0.1.0.exe    5bcb216eef31ea28ed767e4134ab74bd5ac69dfbd365fd249e9e6938e55c986a
  TheseusNavigator-Setup-0.0.1.exe   7c735e88bad2da3347145adba3016c8f626a18b8422289c8c6ba471972e2952b
  TheseusNavigator-0.0.1-portable.exe 008fd84445babeabb401b2bca40ea9466b24b0e6d6c85104da7640c5c5c84521
  ariadne-v0.2.apk                   635c8f04d44ef855a8390b9eeddb8cd2d50622e81cc4e5004e8daffc1bb0425c
2026-07-29 13:54:34 +02:00