From b4c5b1beb4ad8a585f790d0c0d592601e50115bb Mon Sep 17 00:00:00 2001 From: Krystie Date: Tue, 23 Jun 2026 17:24:31 -0700 Subject: [PATCH] feat: add Verified Dev Contact badge + /verify route for signed messages - Add 'Verified Dev Contact' badge on the address page when the address matches the official dev contact (TRsiRzkMWm87ZuWFwPB8YXFGYr5AQZo7fb). Badge includes the signed message + signature, collapsible by default. - Add /verify page with a form that takes address + signature + message and calls the daemon's verifymessage RPC to re-verify. - Add /api/verify server endpoint (POST) that calls the daemon's verifymessage via JSON-RPC and returns { valid: boolean, error? }. - Add 'Verify' link to the main nav. Dev contact proof (verified on DNS2 v5.9.23 mainnet 2026-06-23): - Address: TRsiRzkMWm87ZuWFwPB8YXFGYr5AQZo7fb - Message: 'ROGER THAT, TRIANGLES DEV ADDRESS IS A GO.\n\n5.9.23 IS LIVE.' - Signature: H/gT/bFSL+WFT4F4WYPvDIVAnt0/M2WQy/ypUvhMtdXgAop+Euycakif9QERNcUfPLNF29vDxuXZf1BJjd8Snro= --- .env.example | 5 + src/routes/+layout.svelte | 1 + src/routes/address/[addr]/+page.svelte | 52 +++++++- src/routes/api/verify/+server.ts | 68 +++++++++++ src/routes/verify/+page.svelte | 158 +++++++++++++++++++++++++ 5 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 src/routes/api/verify/+server.ts create mode 100644 src/routes/verify/+page.svelte diff --git a/.env.example b/.env.example index 306146c..01410d2 100644 --- a/.env.example +++ b/.env.example @@ -1 +1,6 @@ TRIANGLES_API_URL=http://127.0.0.1:19112 + +# JSON-RPC credentials for the /api/verify endpoint (daemon's verifymessage) +TRIANGLES_RPC_URL=http://127.0.0.1:19112 +TRIANGLES_RPC_USER=trianglesrpc +TRIANGLES_RPC_PASSWORD= diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 4b7f289..109b875 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -13,6 +13,7 @@ { href: '/nodes', label: 'Nodes' }, { href: '/richlist', label: 'Rich List' }, { href: '/mempool', label: 'Mempool' }, + { href: '/verify', label: 'Verify' }, { href: '/api', label: 'API' } ]; diff --git a/src/routes/address/[addr]/+page.svelte b/src/routes/address/[addr]/+page.svelte index 249b2b3..331c626 100644 --- a/src/routes/address/[addr]/+page.svelte +++ b/src/routes/address/[addr]/+page.svelte @@ -3,8 +3,20 @@ import QRCode from '$lib/components/QRCode.svelte'; import { formatAmount, truncateHash, formatNumber } from '$lib/utils'; + // Verified dev contact — populated on 2026-06-23. The signature is + // hardcoded and matches the proof published on the project website. + // To rotate, generate a new address in TrianglesQt, sign the same + // message text, and replace the three fields below. + const DEV_CONTACT = { + address: 'TRsiRzkMWm87ZuWFwPB8YXFGYr5AQZo7fb', + message: 'ROGER THAT, TRIANGLES DEV ADDRESS IS A GO.\n\n5.9.23 IS LIVE.', + signature: + 'H/gT/bFSL+WFT4F4WYPvDIVAnt0/M2WQy/ypUvhMtdXgAop+Euycakif9QERNcUfPLNF29vDxuXZf1BJjd8Snro=' + }; + let { data } = $props(); - + const isDevContact = data.address === DEV_CONTACT.address; + // Copy address to clipboard let copied = $state(false); function copyAddress() { @@ -20,6 +32,40 @@ +{#if isDevContact} + +
+
+ +

Verified Dev Contact

+
+

+ This address is cryptographically verified as the official Triangles developer contact address. The + signature below was produced by the private key for this address and can be re-verified by anyone + using trianglesd verifymessage or + the /verify tool. +

+
+ + Show signed message proof + +
+
+
Message
+
{DEV_CONTACT.message}
+
+
+
Signature
+ {DEV_CONTACT.signature} +
+
+
+
+{/if} + {#if data.indexError}

Address Details

@@ -27,7 +73,7 @@ Address index is not enabled on this node. Start the daemon with -addressindex=1 to enable address lookups.
- +
@@ -35,7 +81,7 @@
{data.address}
- + +
+ + +{#if result} +
+
+ + {result.valid ? '✓' : '✗'} + +

+ {result.valid ? 'Signature valid' : 'Signature invalid'} +

+
+

+ {#if result.valid} + The signature is cryptographically valid for the provided address and message. The holder + of the private key for this address produced the signature. + {:else} + The signature does not match the address + message combination. + {#if result.error} +
{result.error} + {/if} + {/if} +

+
+{/if} + +
+

How this works

+
    +
  1. The browser sends your input to /api/verify (server-side).
  2. +
  3. + The server calls the Triangles daemon's verifymessageJSON-RPC with the trio. +
  4. +
  5. + The daemon recovers the public key from the signature, hashes it, and compares to the address's + hash. If they match, the signature is valid. +
  6. +
+

+ You can also run the same check yourself from the command line:
+ + trianglesd verifymessage "<address>" "<signature>" "<message>" + +

+