@rel-time/mcp-server 1.2.9 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/index.js +723 -20
- package/package.json +12 -2
- package/server.json +23 -0
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ Official Model Context Protocol (MCP) server for **[Rel-Time](https://rel-time.c
|
|
|
6
6
|
3. **Anchor SHA-256 hashes to the Bitcoin Timechain & Rel-Time VDF** (`POST /v1/anchor`).
|
|
7
7
|
4. **Generate & overlay 64-ray Sun-Stamps onto PDFs and Images** (`reltime-stamped-<name>.pdf` / `.png`).
|
|
8
8
|
5. **Verify Bitcoin block settlement & Merkle proofs** (`GET /v1/proof/{hash}`).
|
|
9
|
-
6. **Self-provision or Reload all 4 Rel-Time Tiers via Bitcoin Lightning or Stripe Card** (`Universal Anchor $3`, `Agent Launch Pack $5 /
|
|
9
|
+
6. **Self-provision or Reload all 4 Rel-Time Tiers via Bitcoin Lightning or Stripe Card** (`Universal Anchor $3`, `Agent Launch Pack $5 / 25`, `Autonomous Agents $50 / 500`, and `Rel-Time Superhighway $399 / 5,000`).
|
|
10
10
|
7. **Run a Superhighway Cryptographic Audit Trail & Local Folder Integrity Check** (`reltime_audit_trail`), generating an interactive HTML Audit Dashboard with Corporate Hardware Passkey (`signer_public_key`) attribution and Bitcoin block verification.
|
|
11
11
|
|
|
12
12
|
---
|
|
@@ -28,9 +28,9 @@ Add the following to your `.mcp.json`, `claude_desktop_config.json`, or `.cursor
|
|
|
28
28
|
|
|
29
29
|
When you start a fresh chat and ask to anchor a file or provision a key, `@rel-time/mcp-server` automatically prompts your agent to ask which tier and payment method (**Bitcoin Lightning** or **Stripe Card**) you want first:
|
|
30
30
|
1. **Universal Anchor (`pack: "universal"`, `$3 / anchor`):** Priority 10-Minute Bitcoin Queue · Standard Mode (Data Integrity + Biometric or Anonymous).
|
|
31
|
-
2. **Agent Launch Pack (`pack: "launch"`, `$5 /
|
|
31
|
+
2. **Agent Launch Pack (`pack: "launch"`, `$5 / 25 Hashes`, max 3 per key):** Priority 10-Minute Bitcoin Queue · Standard Mode · Includes 64-Ray Sun-Stamp, 1-Click Stamped Copy (`.PDF`/`.PNG`), 4-Plate Certificate, and `.JSON` Doomsday Proof.
|
|
32
32
|
3. **Autonomous Agents (`pack: "standard"`, `$50 / 500 Hashes`):** Dynamic 6-Hour Batch Queue · Supports both Temporal Mode (`T_index` sub-second VDF sequencing) and Standard Mode · Reloadable anytime (`+500` credits / `$50`).
|
|
33
|
-
4. **Rel-Time Superhighway (`pack: "enterprise"`, `$
|
|
33
|
+
4. **Rel-Time Superhighway (`pack: "enterprise"`, `$399 / 5,000 Hashes`):** Priority 10-Minute Bitcoin Queue · Temporal Mode (`T_index`) + Standard Mode + Data Integrity Audit & Instant Tamper Detection.
|
|
34
34
|
|
|
35
35
|
Once paid via Lightning or Stripe (or if you pass an existing `rel_key_...` key), the MCP server automatically saves your API key to `~/.reltime/api_key.json` (`0600` permissions) — no app restart or `.zshrc` edits required.
|
|
36
36
|
|
|
@@ -48,4 +48,4 @@ Once paid via Lightning or Stripe (or if you pass an existing `rel_key_...` key)
|
|
|
48
48
|
| `reltime_get_sun_stamp` | **No** | Fetches the deterministic 64-ray SVG Sun-Stamp (`GET /v1/stamp/{hash}`) and returns ready-to-paste Markdown/HTML badge snippets. |
|
|
49
49
|
| `reltime_check_proof` | **No** | Queries `GET /v1/proof/{hash}` for Bitcoin TXID, Block Height, UTC Timestamp, and Merkle inclusion path, and optionally saves/updates the `.json` Doomsday Proof receipt on disk. |
|
|
50
50
|
| `reltime_account_status` | Yes | Checks remaining Hash Credits and tier status (`GET /v1/account`). |
|
|
51
|
-
| `reltime_provision_agent_key` | **No** | Provisions or reloads any of the 4 Rel-Time Tiers (`universal` `$3`, `launch` `$5/
|
|
51
|
+
| `reltime_provision_agent_key` | **No** | Provisions or reloads any of the 4 Rel-Time Tiers (`universal` `$3`, `launch` `$5/25`, `standard` `$50/500`, `enterprise` `$399/5,000`) via **Bitcoin Lightning** or **Stripe Card**. |
|
package/index.js
CHANGED
|
@@ -56,7 +56,7 @@ let LAST_INVOICE_PACK = null;
|
|
|
56
56
|
|
|
57
57
|
const SERVER_INFO = {
|
|
58
58
|
name: "rel-time-mcp-server",
|
|
59
|
-
version: "1.2.
|
|
59
|
+
version: "1.2.11",
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
/**
|
|
@@ -135,13 +135,13 @@ function buildPackSelectionPrompt(contextMessage) {
|
|
|
135
135
|
},
|
|
136
136
|
{
|
|
137
137
|
pack: "launch",
|
|
138
|
-
name: "2. Agent Launch Pack ($5 /
|
|
138
|
+
name: "2. Agent Launch Pack ($5 / 25 Hashes)",
|
|
139
139
|
price_usd: "$5.00",
|
|
140
|
-
credits:
|
|
140
|
+
credits: 25,
|
|
141
141
|
settlement_queue: "Priority 10-Minute Bitcoin Queue",
|
|
142
|
-
hashing_modes: "Standard Mode only (Data Integrity + Biometric or Anonymous)",
|
|
142
|
+
hashing_modes: "Standard Mode only (Data Integrity + Biometric or Anonymous · Max 3 packs per key)",
|
|
143
143
|
payment_methods: ["lightning", "stripe"],
|
|
144
|
-
outputs: "64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + .JSON Doomsday Proof",
|
|
144
|
+
outputs: "64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + 4-Plate Certificate + .JSON Doomsday Proof",
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
pack: "standard",
|
|
@@ -152,21 +152,21 @@ function buildPackSelectionPrompt(contextMessage) {
|
|
|
152
152
|
hashing_modes: "Temporal Mode (T_index sub-second VDF sequencing) + Standard Mode (Biometric or Anonymous)",
|
|
153
153
|
payment_methods: ["lightning", "stripe"],
|
|
154
154
|
outputs:
|
|
155
|
-
"64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + .JSON Doomsday Proof + Reloadable anytime (+500 credits / $50)",
|
|
155
|
+
"64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + 4-Plate Certificate + .JSON Doomsday Proof + Reloadable anytime (+500 credits / $50)",
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
158
|
pack: "enterprise",
|
|
159
|
-
name: "4. Rel-Time Superhighway ($
|
|
160
|
-
price_usd: "$
|
|
159
|
+
name: "4. Rel-Time Superhighway ($399 / 5,000 Hashes)",
|
|
160
|
+
price_usd: "$399.00",
|
|
161
161
|
credits: 5000,
|
|
162
162
|
settlement_queue: "Priority 10-Minute Bitcoin Queue",
|
|
163
|
-
hashing_modes: "Temporal Mode (T_index) + Standard Mode +
|
|
163
|
+
hashing_modes: "Temporal Mode (T_index) + Standard Mode + Data Integrity Audit & Instant Tamper Detection",
|
|
164
164
|
payment_methods: ["lightning", "stripe"],
|
|
165
|
-
outputs: "64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + Certificate
|
|
165
|
+
outputs: "64-Ray Sun-Stamp SVG + 1-Click Stamped Copy (.PDF/.PNG) + 4-Plate Certificate + Forensic Audit Report + .JSON Proof",
|
|
166
166
|
},
|
|
167
167
|
],
|
|
168
168
|
next_step:
|
|
169
|
-
"Ask the user which tier (`universal` $3, `launch` $5/
|
|
169
|
+
"Ask the user which tier (`universal` $3, `launch` $5/25, `standard` $50/500, or `enterprise` $399/5,000) and which payment method (`lightning` or `stripe`) they prefer, then call `reltime_provision_agent_key({ action: 'create_invoice', pack, payment_method })`.",
|
|
170
170
|
};
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -1527,11 +1527,545 @@ function generateAuditReportHtml(audit) {
|
|
|
1527
1527
|
</html>`;
|
|
1528
1528
|
}
|
|
1529
1529
|
|
|
1530
|
+
function inferMimeTypeFromFileName(fileName) {
|
|
1531
|
+
if (!fileName || fileName === "Zero-Knowledge Hash Payload") {
|
|
1532
|
+
return "application/octet-stream (Zero-Knowledge)";
|
|
1533
|
+
}
|
|
1534
|
+
const lower = String(fileName).toLowerCase();
|
|
1535
|
+
if (lower.endsWith(".pdf")) return "application/pdf";
|
|
1536
|
+
if (lower.endsWith(".png")) return "image/png";
|
|
1537
|
+
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
1538
|
+
if (lower.endsWith(".webp")) return "image/webp";
|
|
1539
|
+
if (lower.endsWith(".svg")) return "image/svg+xml";
|
|
1540
|
+
if (lower.endsWith(".json")) return "application/json";
|
|
1541
|
+
if (lower.endsWith(".csv")) return "text/csv";
|
|
1542
|
+
if (lower.endsWith(".txt") || lower.endsWith(".md")) return "text/plain";
|
|
1543
|
+
if (lower.endsWith(".mp4")) return "video/mp4";
|
|
1544
|
+
if (lower.endsWith(".mp3")) return "audio/mpeg";
|
|
1545
|
+
if (lower.endsWith(".wav")) return "audio/wav";
|
|
1546
|
+
if (lower.endsWith(".zip")) return "application/zip";
|
|
1547
|
+
return "application/octet-stream";
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
function generateProvenanceCertificateHtml(input = {}) {
|
|
1551
|
+
const fileName = escapeHtml(input.fileName || "Zero-Knowledge Hash Payload");
|
|
1552
|
+
const fileSize = escapeHtml(input.fileSize || "Zero-Knowledge (32-Byte Digest)");
|
|
1553
|
+
const mimeType = escapeHtml(input.mimeType || inferMimeTypeFromFileName(input.fileName));
|
|
1554
|
+
|
|
1555
|
+
const originalHash = escapeHtml(String(input.originalFileHash || input.attestedHash || "").toLowerCase());
|
|
1556
|
+
const attestedHash = escapeHtml(String(input.attestedHash || input.originalFileHash || "").toLowerCase());
|
|
1557
|
+
const signerPubKey = input.signerPublicKey ? escapeHtml(String(input.signerPublicKey)) : null;
|
|
1558
|
+
|
|
1559
|
+
const isStandard = String(input.anchorMode || "standard").toLowerCase() === "standard";
|
|
1560
|
+
const modeLabel = isStandard
|
|
1561
|
+
? "MODE: STANDARD (DATA INTEGRITY)"
|
|
1562
|
+
: "MODE: TEMPORAL (VDF SEQUENCE)";
|
|
1563
|
+
|
|
1564
|
+
const tIndex = escapeHtml(String(input.tIndex || "PENDING VDF SNAPSHOT"));
|
|
1565
|
+
const formattedTicks =
|
|
1566
|
+
typeof input.vdfTicks === "number"
|
|
1567
|
+
? `${input.vdfTicks.toLocaleString()} Ticks`
|
|
1568
|
+
: escapeHtml(String(input.vdfTicks || "0 Ticks"));
|
|
1569
|
+
|
|
1570
|
+
const isSettled = input.status === "settled" || Boolean(input.blockHeight);
|
|
1571
|
+
const blockHeightDisplay = input.blockHeight
|
|
1572
|
+
? `#${Number(input.blockHeight).toLocaleString()}`
|
|
1573
|
+
: "PENDING NEXT BITCOIN BLOCK";
|
|
1574
|
+
const blockTimeDisplay = escapeHtml(
|
|
1575
|
+
input.blockTimeUtc || (isSettled ? "CONFIRMED ON BITCOIN MAINNET" : "PENDING BLOCK HEADER UTC")
|
|
1576
|
+
);
|
|
1577
|
+
const merkleProofDisplay =
|
|
1578
|
+
typeof input.merkleProofCount === "number" && input.merkleProofCount > 0
|
|
1579
|
+
? `[ ${input.merkleProofCount} SIBLING HASHES ]`
|
|
1580
|
+
: isSettled
|
|
1581
|
+
? "[ INCLUDED IN MERKLE ROOT ]"
|
|
1582
|
+
: "PENDING";
|
|
1583
|
+
const txidDisplay = escapeHtml(String(input.txid || "PENDING NEXT BITCOIN BLOCK"));
|
|
1584
|
+
const finalityValueClass = isSettled ? "data-value green" : "data-value orange";
|
|
1585
|
+
|
|
1586
|
+
return `<!DOCTYPE html>
|
|
1587
|
+
<html lang="en">
|
|
1588
|
+
<head>
|
|
1589
|
+
<meta charset="UTF-8">
|
|
1590
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
|
|
1591
|
+
<title>Rel-Time Sovereign Provenance Certificate - ${fileName}</title>
|
|
1592
|
+
<style>
|
|
1593
|
+
* { box-sizing: border-box; }
|
|
1594
|
+
:root {
|
|
1595
|
+
--bg-body: #050507;
|
|
1596
|
+
--bg-monument: linear-gradient(180deg, #181a20 0%, #0d0e12 50%, #08090c 100%);
|
|
1597
|
+
--border-monument: #3f3f46;
|
|
1598
|
+
--monument-shadow: inset 0 1px 0 rgba(255,255,255,0.15), 0 30px 70px rgba(0,0,0,0.95);
|
|
1599
|
+
--bg-plate: rgba(0, 0, 0, 0.45);
|
|
1600
|
+
--border-plate: #27272a;
|
|
1601
|
+
--plate-title: #d4d4d8;
|
|
1602
|
+
--text-label: #71717a;
|
|
1603
|
+
--text-value: #f4f4f5;
|
|
1604
|
+
--bg-value: #050507;
|
|
1605
|
+
--border-value: #27272a;
|
|
1606
|
+
--accent-orange: #fb923c;
|
|
1607
|
+
--accent-green: #4ade80;
|
|
1608
|
+
--accent-cyan: #22d3ee;
|
|
1609
|
+
--anchored-box-bg: rgba(251, 146, 60, 0.06);
|
|
1610
|
+
--anchored-box-border: rgba(251, 146, 60, 0.65);
|
|
1611
|
+
--anchored-badge-bg: rgba(251, 146, 60, 0.15);
|
|
1612
|
+
--mode-pill-bg: #18181b;
|
|
1613
|
+
--mode-pill-border: #52525b;
|
|
1614
|
+
--mode-pill-color: #f4f4f5;
|
|
1615
|
+
--theme-btn-bg: #27272a;
|
|
1616
|
+
--theme-btn-border: #52525b;
|
|
1617
|
+
--theme-btn-color: #f4f4f5;
|
|
1618
|
+
--solar-shadow: drop-shadow(0 0 25px rgba(255, 95, 31, 0.45));
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
body.light-mode {
|
|
1622
|
+
--bg-body: #e4e4e7;
|
|
1623
|
+
--bg-monument: #ffffff;
|
|
1624
|
+
--border-monument: #cbd5e1;
|
|
1625
|
+
--monument-shadow: 0 20px 45px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.05);
|
|
1626
|
+
--bg-plate: #f8fafc;
|
|
1627
|
+
--border-plate: #e2e8f0;
|
|
1628
|
+
--plate-title: #0f172a;
|
|
1629
|
+
--text-label: #64748b;
|
|
1630
|
+
--text-value: #09090b;
|
|
1631
|
+
--bg-value: #ffffff;
|
|
1632
|
+
--border-value: #cbd5e1;
|
|
1633
|
+
--accent-orange: #ea580c;
|
|
1634
|
+
--accent-green: #15803d;
|
|
1635
|
+
--accent-cyan: #0891b2;
|
|
1636
|
+
--anchored-box-bg: rgba(234, 88, 12, 0.08);
|
|
1637
|
+
--anchored-box-border: rgba(234, 88, 12, 0.75);
|
|
1638
|
+
--anchored-badge-bg: rgba(234, 88, 12, 0.12);
|
|
1639
|
+
--mode-pill-bg: #f1f5f9;
|
|
1640
|
+
--mode-pill-border: #cbd5e1;
|
|
1641
|
+
--mode-pill-color: #0f172a;
|
|
1642
|
+
--theme-btn-bg: #f1f5f9;
|
|
1643
|
+
--theme-btn-border: #cbd5e1;
|
|
1644
|
+
--theme-btn-color: #0f172a;
|
|
1645
|
+
--solar-shadow: drop-shadow(0 0 20px rgba(234, 88, 12, 0.3));
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
body {
|
|
1649
|
+
background-color: var(--bg-body);
|
|
1650
|
+
color: var(--text-value);
|
|
1651
|
+
font-family: 'Fira Code', 'SFMono-Regular', Consolas, Menlo, monospace;
|
|
1652
|
+
margin: 0;
|
|
1653
|
+
padding: 2rem 1rem;
|
|
1654
|
+
display: flex;
|
|
1655
|
+
flex-direction: column;
|
|
1656
|
+
align-items: center;
|
|
1657
|
+
transition: background-color 0.3s ease, color 0.3s ease;
|
|
1658
|
+
min-height: 100vh;
|
|
1659
|
+
overflow-x: hidden;
|
|
1660
|
+
width: 100%;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
.monument {
|
|
1664
|
+
max-width: 960px;
|
|
1665
|
+
width: 100%;
|
|
1666
|
+
background: var(--bg-monument);
|
|
1667
|
+
border: 2px solid var(--border-monument);
|
|
1668
|
+
box-shadow: var(--monument-shadow);
|
|
1669
|
+
border-radius: 6px;
|
|
1670
|
+
padding: 2.5rem;
|
|
1671
|
+
position: relative;
|
|
1672
|
+
transition: all 0.3s ease;
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
.header-bar {
|
|
1676
|
+
display: flex;
|
|
1677
|
+
justify-content: space-between;
|
|
1678
|
+
align-items: flex-start;
|
|
1679
|
+
border-bottom: 2px solid var(--border-plate);
|
|
1680
|
+
padding-bottom: 1.5rem;
|
|
1681
|
+
margin-bottom: 2rem;
|
|
1682
|
+
gap: 1.5rem;
|
|
1683
|
+
flex-wrap: wrap;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
.brand-group { display: flex; flex-direction: column; }
|
|
1687
|
+
.brand-logo {
|
|
1688
|
+
display: inline-flex;
|
|
1689
|
+
align-items: center;
|
|
1690
|
+
gap: 0.3rem;
|
|
1691
|
+
font-size: 1.5rem;
|
|
1692
|
+
font-weight: 800;
|
|
1693
|
+
letter-spacing: 0.2em;
|
|
1694
|
+
line-height: 1.2;
|
|
1695
|
+
}
|
|
1696
|
+
.logo-bracket { color: var(--accent-orange); font-weight: 900; }
|
|
1697
|
+
.logo-text { color: var(--text-value); letter-spacing: 0.22em; }
|
|
1698
|
+
.brand-sub {
|
|
1699
|
+
margin: 0.45rem 0 0 0;
|
|
1700
|
+
color: var(--text-label);
|
|
1701
|
+
font-size: 0.68rem;
|
|
1702
|
+
letter-spacing: 0.16em;
|
|
1703
|
+
text-transform: uppercase;
|
|
1704
|
+
}
|
|
1705
|
+
.header-actions {
|
|
1706
|
+
display: flex;
|
|
1707
|
+
align-items: center;
|
|
1708
|
+
gap: 0.75rem;
|
|
1709
|
+
flex-wrap: wrap;
|
|
1710
|
+
}
|
|
1711
|
+
.mode-pill {
|
|
1712
|
+
background: var(--mode-pill-bg);
|
|
1713
|
+
border: 1px solid var(--mode-pill-border);
|
|
1714
|
+
color: var(--mode-pill-color);
|
|
1715
|
+
padding: 0.4rem 0.8rem;
|
|
1716
|
+
font-size: 0.7rem;
|
|
1717
|
+
letter-spacing: 0.15em;
|
|
1718
|
+
text-transform: uppercase;
|
|
1719
|
+
font-weight: 600;
|
|
1720
|
+
border-radius: 4px;
|
|
1721
|
+
white-space: nowrap;
|
|
1722
|
+
}
|
|
1723
|
+
.theme-btn {
|
|
1724
|
+
background: var(--theme-btn-bg);
|
|
1725
|
+
border: 1px solid var(--theme-btn-border);
|
|
1726
|
+
color: var(--theme-btn-color);
|
|
1727
|
+
padding: 0.4rem 0.8rem;
|
|
1728
|
+
font-size: 0.7rem;
|
|
1729
|
+
letter-spacing: 0.15em;
|
|
1730
|
+
text-transform: uppercase;
|
|
1731
|
+
font-weight: 700;
|
|
1732
|
+
cursor: pointer;
|
|
1733
|
+
border-radius: 4px;
|
|
1734
|
+
transition: all 0.2s ease;
|
|
1735
|
+
font-family: inherit;
|
|
1736
|
+
display: inline-flex;
|
|
1737
|
+
align-items: center;
|
|
1738
|
+
gap: 0.35rem;
|
|
1739
|
+
}
|
|
1740
|
+
.theme-btn:hover {
|
|
1741
|
+
border-color: var(--accent-orange);
|
|
1742
|
+
color: var(--accent-orange);
|
|
1743
|
+
}
|
|
1744
|
+
.plate {
|
|
1745
|
+
background: var(--bg-plate);
|
|
1746
|
+
border: 1px solid var(--border-plate);
|
|
1747
|
+
box-shadow: inset 0 2px 6px rgba(0,0,0,0.4);
|
|
1748
|
+
padding: 1.5rem;
|
|
1749
|
+
margin-bottom: 1.75rem;
|
|
1750
|
+
border-radius: 4px;
|
|
1751
|
+
transition: all 0.3s ease;
|
|
1752
|
+
}
|
|
1753
|
+
.plate-title {
|
|
1754
|
+
color: var(--plate-title);
|
|
1755
|
+
font-size: 0.75rem;
|
|
1756
|
+
font-weight: bold;
|
|
1757
|
+
letter-spacing: 0.2em;
|
|
1758
|
+
border-bottom: 1px solid var(--border-plate);
|
|
1759
|
+
padding-bottom: 0.6rem;
|
|
1760
|
+
margin-bottom: 1.25rem;
|
|
1761
|
+
text-transform: uppercase;
|
|
1762
|
+
display: flex;
|
|
1763
|
+
justify-content: space-between;
|
|
1764
|
+
align-items: center;
|
|
1765
|
+
flex-wrap: wrap;
|
|
1766
|
+
gap: 0.5rem;
|
|
1767
|
+
}
|
|
1768
|
+
.plate-subtitle {
|
|
1769
|
+
font-size: 0.65rem;
|
|
1770
|
+
color: var(--text-label);
|
|
1771
|
+
letter-spacing: 0.12em;
|
|
1772
|
+
}
|
|
1773
|
+
.data-row { margin-bottom: 1rem; }
|
|
1774
|
+
.data-row:last-child { margin-bottom: 0; }
|
|
1775
|
+
.data-label {
|
|
1776
|
+
color: var(--text-label);
|
|
1777
|
+
font-size: 0.68rem;
|
|
1778
|
+
letter-spacing: 0.14em;
|
|
1779
|
+
text-transform: uppercase;
|
|
1780
|
+
margin-bottom: 0.35rem;
|
|
1781
|
+
display: flex;
|
|
1782
|
+
justify-content: space-between;
|
|
1783
|
+
align-items: center;
|
|
1784
|
+
flex-wrap: wrap;
|
|
1785
|
+
gap: 0.4rem;
|
|
1786
|
+
}
|
|
1787
|
+
.data-value {
|
|
1788
|
+
color: var(--text-value);
|
|
1789
|
+
font-size: 0.82rem;
|
|
1790
|
+
word-break: break-all;
|
|
1791
|
+
background: var(--bg-value);
|
|
1792
|
+
padding: 0.65rem 0.85rem;
|
|
1793
|
+
border: 1px solid var(--border-value);
|
|
1794
|
+
box-shadow: inset 0 1px 3px rgba(0,0,0,0.5);
|
|
1795
|
+
border-radius: 2px;
|
|
1796
|
+
line-height: 1.45;
|
|
1797
|
+
}
|
|
1798
|
+
.data-value.cyan { color: var(--accent-cyan); border-color: rgba(34, 211, 238, 0.3); }
|
|
1799
|
+
.data-value.orange { color: var(--accent-orange); border-color: rgba(251, 146, 60, 0.3); }
|
|
1800
|
+
.data-value.green { color: var(--accent-green); border-color: rgba(74, 222, 128, 0.35); }
|
|
1801
|
+
.anchored-box {
|
|
1802
|
+
color: var(--accent-orange) !important;
|
|
1803
|
+
border: 1px solid var(--anchored-box-border) !important;
|
|
1804
|
+
background: var(--anchored-box-bg) !important;
|
|
1805
|
+
box-shadow: 0 0 18px rgba(251, 146, 60, 0.15), inset 0 1px 3px rgba(0,0,0,0.5) !important;
|
|
1806
|
+
font-weight: 600;
|
|
1807
|
+
}
|
|
1808
|
+
.anchored-badge {
|
|
1809
|
+
background: var(--anchored-badge-bg);
|
|
1810
|
+
color: var(--accent-orange);
|
|
1811
|
+
border: 1px solid var(--anchored-box-border);
|
|
1812
|
+
padding: 0.2rem 0.55rem;
|
|
1813
|
+
font-size: 0.62rem;
|
|
1814
|
+
font-weight: bold;
|
|
1815
|
+
letter-spacing: 0.12em;
|
|
1816
|
+
border-radius: 3px;
|
|
1817
|
+
}
|
|
1818
|
+
.solar-vault {
|
|
1819
|
+
display: flex;
|
|
1820
|
+
flex-direction: column;
|
|
1821
|
+
align-items: center;
|
|
1822
|
+
text-align: center;
|
|
1823
|
+
margin-bottom: 1.25rem;
|
|
1824
|
+
}
|
|
1825
|
+
.stamp-box {
|
|
1826
|
+
width: 240px;
|
|
1827
|
+
height: 240px;
|
|
1828
|
+
margin: 0.5rem auto 1rem auto;
|
|
1829
|
+
filter: var(--solar-shadow);
|
|
1830
|
+
max-width: 100%;
|
|
1831
|
+
}
|
|
1832
|
+
.stamp-box svg { width: 100%; height: 100%; }
|
|
1833
|
+
.grid-3 {
|
|
1834
|
+
display: grid;
|
|
1835
|
+
grid-template-columns: repeat(3, 1fr);
|
|
1836
|
+
gap: 1rem;
|
|
1837
|
+
margin-bottom: 1rem;
|
|
1838
|
+
}
|
|
1839
|
+
.grid-3:last-child { margin-bottom: 0; }
|
|
1840
|
+
@media (max-width: 640px) {
|
|
1841
|
+
body { padding: 0.5rem 0.35rem; }
|
|
1842
|
+
.monument { padding: 1.25rem 0.85rem; border-width: 1px; }
|
|
1843
|
+
.header-bar { flex-direction: column; align-items: flex-start; gap: 1rem; }
|
|
1844
|
+
.grid-3 { grid-template-columns: 1fr; gap: 0.75rem; }
|
|
1845
|
+
.stamp-box { width: 210px; height: 210px; }
|
|
1846
|
+
}
|
|
1847
|
+
@media print {
|
|
1848
|
+
body { background: #ffffff !important; color: #000000 !important; padding: 0 !important; }
|
|
1849
|
+
.theme-btn { display: none !important; }
|
|
1850
|
+
.monument { border: 1px solid #cbd5e1 !important; box-shadow: none !important; background: #ffffff !important; padding: 1.5rem !important; max-width: 100% !important; }
|
|
1851
|
+
.plate { background: #f8fafc !important; border: 1px solid #e2e8f0 !important; box-shadow: none !important; }
|
|
1852
|
+
.data-value { background: #ffffff !important; border: 1px solid #cbd5e1 !important; color: #000000 !important; }
|
|
1853
|
+
}
|
|
1854
|
+
</style>
|
|
1855
|
+
<script src="https://cdn.jsdelivr.net/npm/qrcode-generator@1.4.4/qrcode.min.js"></script>
|
|
1856
|
+
</head>
|
|
1857
|
+
<body>
|
|
1858
|
+
<div class="monument">
|
|
1859
|
+
<div class="header-bar">
|
|
1860
|
+
<div class="brand-group">
|
|
1861
|
+
<div class="brand-logo">
|
|
1862
|
+
<span class="logo-bracket">[</span>
|
|
1863
|
+
<span class="logo-text">REL-TIME</span>
|
|
1864
|
+
<span class="logo-bracket">]</span>
|
|
1865
|
+
</div>
|
|
1866
|
+
<p class="brand-sub">SOVEREIGN CRYPTOGRAPHIC PROVENANCE CERTIFICATE</p>
|
|
1867
|
+
</div>
|
|
1868
|
+
<div class="header-actions">
|
|
1869
|
+
<div class="mode-pill">${modeLabel}</div>
|
|
1870
|
+
<button class="theme-btn" onclick="window.print()" aria-label="Print or Save as PDF">🖨️ PRINT / PDF</button>
|
|
1871
|
+
<button id="theme-toggle" class="theme-btn" onclick="toggleTheme()" aria-label="Toggle light or dark theme">☀️ LIGHT</button>
|
|
1872
|
+
</div>
|
|
1873
|
+
</div>
|
|
1874
|
+
|
|
1875
|
+
<div class="plate">
|
|
1876
|
+
<div class="plate-title">
|
|
1877
|
+
<span>Asset Identification</span>
|
|
1878
|
+
<span class="plate-subtitle">LOCAL ZERO-KNOWLEDGE SHA-256</span>
|
|
1879
|
+
</div>
|
|
1880
|
+
<div class="grid-3">
|
|
1881
|
+
<div class="data-row" style="margin:0;">
|
|
1882
|
+
<div class="data-label">File Name</div>
|
|
1883
|
+
<div class="data-value">${fileName}</div>
|
|
1884
|
+
</div>
|
|
1885
|
+
<div class="data-row" style="margin:0;">
|
|
1886
|
+
<div class="data-label">File Size</div>
|
|
1887
|
+
<div class="data-value">${fileSize}</div>
|
|
1888
|
+
</div>
|
|
1889
|
+
<div class="data-row" style="margin:0;">
|
|
1890
|
+
<div class="data-label">MIME Type</div>
|
|
1891
|
+
<div class="data-value">${mimeType}</div>
|
|
1892
|
+
</div>
|
|
1893
|
+
</div>
|
|
1894
|
+
</div>
|
|
1895
|
+
|
|
1896
|
+
<div class="plate">
|
|
1897
|
+
<div class="plate-title">
|
|
1898
|
+
<span>Plate I — Cryptographic Payload & Ownership</span>
|
|
1899
|
+
<span class="plate-subtitle" style="color:var(--accent-orange);">${
|
|
1900
|
+
signerPubKey ? "BIOMETRIC PASSKEY ATTESTED" : "ANONYMOUS PURITY"
|
|
1901
|
+
}</span>
|
|
1902
|
+
</div>
|
|
1903
|
+
<div class="data-row">
|
|
1904
|
+
<div class="data-label">[ THE WHAT ] ZERO-KNOWLEDGE FILE HASH (SHA-256)</div>
|
|
1905
|
+
<div class="data-value cyan">${originalHash}</div>
|
|
1906
|
+
</div>
|
|
1907
|
+
<div class="data-row">
|
|
1908
|
+
<div class="data-label">[ THE WHO ] SIGNATORY PUBLIC KEY</div>
|
|
1909
|
+
<div class="data-value cyan">${
|
|
1910
|
+
signerPubKey || "[ ANONYMOUS — RAW DATA INTEGRITY (NO PASSKEY) ]"
|
|
1911
|
+
}</div>
|
|
1912
|
+
</div>
|
|
1913
|
+
<div class="data-row">
|
|
1914
|
+
<div class="data-label">
|
|
1915
|
+
<span>ATTESTED IDENTITY HASH • GENERATES THE 64-RAY SUN-STAMP</span>
|
|
1916
|
+
<span class="anchored-badge">★ ANCHORED TO BITCOIN MERKLE TREE</span>
|
|
1917
|
+
</div>
|
|
1918
|
+
<div class="data-value anchored-box">${attestedHash}</div>
|
|
1919
|
+
</div>
|
|
1920
|
+
</div>
|
|
1921
|
+
|
|
1922
|
+
<div class="plate">
|
|
1923
|
+
<div class="plate-title">
|
|
1924
|
+
<span>Plate II — The Solar Seal & Thermodynamic Clock</span>
|
|
1925
|
+
<span class="plate-subtitle">SEEDED BY ATTESTED IDENTITY HASH</span>
|
|
1926
|
+
</div>
|
|
1927
|
+
<div class="solar-vault">
|
|
1928
|
+
<div class="stamp-box" id="stamp-mount"></div>
|
|
1929
|
+
</div>
|
|
1930
|
+
<div class="data-row">
|
|
1931
|
+
<div class="data-label">
|
|
1932
|
+
<span>[ THE WHEN ] THERMODYNAMIC PROOF (T_INDEX)</span>
|
|
1933
|
+
<span class="plate-subtitle">${isStandard ? "STATIC BLOCK SEED" : "VDF CLOCK SNAPSHOT"}</span>
|
|
1934
|
+
</div>
|
|
1935
|
+
<div class="data-value orange">${tIndex}</div>
|
|
1936
|
+
</div>
|
|
1937
|
+
<div class="data-row">
|
|
1938
|
+
<div class="data-label">SOLAR VDF TICKS ELAPSED SINCE LAST BITCOIN BLOCK</div>
|
|
1939
|
+
<div class="data-value orange" style="font-weight:bold;">${
|
|
1940
|
+
isStandard ? "0 (Bypassed — Standard Mode)" : formattedTicks
|
|
1941
|
+
}</div>
|
|
1942
|
+
</div>
|
|
1943
|
+
</div>
|
|
1944
|
+
|
|
1945
|
+
<div class="plate">
|
|
1946
|
+
<div class="plate-title">
|
|
1947
|
+
<span>Plate III — Bitcoin Timechain Finality</span>
|
|
1948
|
+
<span class="plate-subtitle" style="color:${
|
|
1949
|
+
isSettled ? "var(--accent-green)" : "var(--accent-orange)"
|
|
1950
|
+
};">${isSettled ? "MAINNET OP_RETURN SETTLEMENT" : "AWAITING BLOCK SETTLEMENT"}</span>
|
|
1951
|
+
</div>
|
|
1952
|
+
<div class="grid-3">
|
|
1953
|
+
<div class="data-row" style="margin:0;">
|
|
1954
|
+
<div class="data-label">Bitcoin Block Height</div>
|
|
1955
|
+
<div class="data-value ${isSettled ? "green" : "orange"}">${blockHeightDisplay}</div>
|
|
1956
|
+
</div>
|
|
1957
|
+
<div class="data-row" style="margin:0;">
|
|
1958
|
+
<div class="data-label">Block Timestamp (UTC)</div>
|
|
1959
|
+
<div class="data-value ${isSettled ? "green" : "orange"}">${blockTimeDisplay}</div>
|
|
1960
|
+
</div>
|
|
1961
|
+
<div class="data-row" style="margin:0;">
|
|
1962
|
+
<div class="data-label">Merkle Proof Path</div>
|
|
1963
|
+
<div class="data-value ${isSettled ? "green" : "orange"}">${merkleProofDisplay}</div>
|
|
1964
|
+
</div>
|
|
1965
|
+
</div>
|
|
1966
|
+
<div class="data-row">
|
|
1967
|
+
<div class="data-label">BITCOIN OP_RETURN TRANSACTION ID (TXID)</div>
|
|
1968
|
+
<div class="${finalityValueClass}">${txidDisplay}</div>
|
|
1969
|
+
</div>
|
|
1970
|
+
</div>
|
|
1971
|
+
</div>
|
|
1972
|
+
|
|
1973
|
+
<script>
|
|
1974
|
+
function toggleTheme() {
|
|
1975
|
+
const body = document.body;
|
|
1976
|
+
const btn = document.getElementById('theme-toggle');
|
|
1977
|
+
const isLight = body.classList.toggle('light-mode');
|
|
1978
|
+
if (btn) btn.innerHTML = isLight ? '🌙 DARK' : '☀️ LIGHT';
|
|
1979
|
+
try { localStorage.setItem('reltime_cert_theme', isLight ? 'light' : 'dark'); } catch(e) {}
|
|
1980
|
+
}
|
|
1981
|
+
try {
|
|
1982
|
+
if (localStorage.getItem('reltime_cert_theme') === 'light') {
|
|
1983
|
+
document.body.classList.add('light-mode');
|
|
1984
|
+
const btn = document.getElementById('theme-toggle');
|
|
1985
|
+
if (btn) btn.innerHTML = '🌙 DARK';
|
|
1986
|
+
}
|
|
1987
|
+
} catch(e) {}
|
|
1988
|
+
|
|
1989
|
+
function generateBWStamp() {
|
|
1990
|
+
const attestedHash = ${JSON.stringify(attestedHash)};
|
|
1991
|
+
const verifyUrl = 'https://rel-time.com/verify?t=' + attestedHash;
|
|
1992
|
+
const qr = qrcode(0, 'L');
|
|
1993
|
+
qr.addData(verifyUrl);
|
|
1994
|
+
qr.make();
|
|
1995
|
+
|
|
1996
|
+
const moduleCount = qr.getModuleCount();
|
|
1997
|
+
const quietZone = 3;
|
|
1998
|
+
const gridSize = 55;
|
|
1999
|
+
const offset = Math.floor((gridSize - moduleCount) / 2);
|
|
2000
|
+
const center = gridSize / 2;
|
|
2001
|
+
const cellSize = 3.85;
|
|
2002
|
+
const maxRadiusPx = 104.0;
|
|
2003
|
+
|
|
2004
|
+
let svgContent = '<svg viewBox="22 22 356 356" width="240" height="240" xmlns="http://www.w3.org/2000/svg">';
|
|
2005
|
+
svgContent += '<a href="' + verifyUrl + '" target="_blank" rel="noopener noreferrer" style="cursor:pointer;">';
|
|
2006
|
+
svgContent += '<circle cx="200" cy="200" r="109" fill="#ffffff" stroke="#000000" stroke-width="2" stroke-opacity="1"/>';
|
|
2007
|
+
|
|
2008
|
+
let qrDots = '';
|
|
2009
|
+
let noiseDots = '';
|
|
2010
|
+
|
|
2011
|
+
for (let r = 0; r < gridSize; r++) {
|
|
2012
|
+
for (let c = 0; c < gridSize; c++) {
|
|
2013
|
+
const dx = (c - center + 0.5) * cellSize;
|
|
2014
|
+
const dy = (r - center + 0.5) * cellSize;
|
|
2015
|
+
const distPx = Math.sqrt(dx * dx + dy * dy);
|
|
2016
|
+
const qrR = r - offset;
|
|
2017
|
+
const qrC = c - offset;
|
|
2018
|
+
const x = 200 + (c - center) * cellSize;
|
|
2019
|
+
const y = 200 + (r - center) * cellSize;
|
|
2020
|
+
|
|
2021
|
+
if (qrR >= 0 && qrR < moduleCount && qrC >= 0 && qrC < moduleCount) {
|
|
2022
|
+
if (qr.isDark(qrR, qrC)) {
|
|
2023
|
+
qrDots += '<rect x="' + x.toFixed(2) + '" y="' + y.toFixed(2) + '" width="' + (cellSize + 0.22).toFixed(2) + '" height="' + (cellSize + 0.22).toFixed(2) + '" />';
|
|
2024
|
+
}
|
|
2025
|
+
} else if (qrR >= -quietZone && qrR < moduleCount + quietZone && qrC >= -quietZone && qrC < moduleCount + quietZone) {
|
|
2026
|
+
} else if (distPx <= maxRadiusPx) {
|
|
2027
|
+
const seed = Math.sin(r * 12.9898 + c * 78.233) * 43758.5453;
|
|
2028
|
+
if ((seed - Math.floor(seed)) > 0.5) {
|
|
2029
|
+
noiseDots += '<rect x="' + x.toFixed(2) + '" y="' + y.toFixed(2) + '" width="' + (cellSize + 0.2).toFixed(2) + '" height="' + (cellSize + 0.2).toFixed(2) + '" />';
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
svgContent += '<g fill="#000000" transform="rotate(14 200 200)">' + qrDots + '</g>';
|
|
2036
|
+
svgContent += '<g fill="#000000" transform="rotate(14 200 200)">' + noiseDots + '</g>';
|
|
2037
|
+
|
|
2038
|
+
const hash = attestedHash;
|
|
2039
|
+
let radials = '<g>';
|
|
2040
|
+
for (let i = 0; i < 64; i++) {
|
|
2041
|
+
const val = parseInt(hash[i] || '0', 16) || 0;
|
|
2042
|
+
const r_length = 15 + (val / 15) * 45;
|
|
2043
|
+
const r_inner = 115;
|
|
2044
|
+
const a = (i * 360 / 64 - 90) * Math.PI / 180;
|
|
2045
|
+
const x1 = 200 + r_inner * Math.cos(a);
|
|
2046
|
+
const y1 = 200 + r_inner * Math.sin(a);
|
|
2047
|
+
const x2 = 200 + (r_inner + r_length) * Math.cos(a);
|
|
2048
|
+
const y2 = 200 + (r_inner + r_length) * Math.sin(a);
|
|
2049
|
+
const dynamicRayColor = (val % 2 === 1) ? '#facc15' : '#ea580c';
|
|
2050
|
+
radials += '<line x1="' + x1.toFixed(2) + '" y1="' + y1.toFixed(2) + '" x2="' + x2.toFixed(2) + '" y2="' + y2.toFixed(2) + '" stroke="' + dynamicRayColor + '" stroke-width="2.5" stroke-linecap="round" />';
|
|
2051
|
+
}
|
|
2052
|
+
radials += '</g></a></svg>';
|
|
2053
|
+
svgContent += radials;
|
|
2054
|
+
|
|
2055
|
+
const mount = document.getElementById('stamp-mount');
|
|
2056
|
+
if (mount) mount.innerHTML = svgContent;
|
|
2057
|
+
}
|
|
2058
|
+
generateBWStamp();
|
|
2059
|
+
</script>
|
|
2060
|
+
</body>
|
|
2061
|
+
</html>`;
|
|
2062
|
+
}
|
|
2063
|
+
|
|
1530
2064
|
const TOOLS = [
|
|
1531
2065
|
{
|
|
1532
2066
|
name: "reltime_anchor_file",
|
|
1533
2067
|
description:
|
|
1534
|
-
"Zero-knowledge file anchoring + 1-Click Stamped Copy: Computes the SHA-256 hash of a local file ENTIRELY ON THE LOCAL MACHINE (the file never leaves the user's computer), supports both Anonymous and Biometric (Passkey) Anchors, anchors the 64-char hash to the Bitcoin Timechain via Rel-Time, saves the 64-ray Sun-Stamp SVG
|
|
2068
|
+
"Zero-knowledge file anchoring + 1-Click Stamped Copy + 4-Plate Provenance Certificate: Computes the SHA-256 hash of a local file ENTIRELY ON THE LOCAL MACHINE (the file never leaves the user's computer), supports both Anonymous and Biometric (Passkey) Anchors, anchors the 64-char hash to the Bitcoin Timechain via Rel-Time, saves the 64-ray Sun-Stamp SVG, JSON Doomsday Proof, 4-Plate Sovereign Cryptographic Provenance Certificate (`reltime-certificate-<name>.html`), and automatically creates a Stamped Copy (`reltime-stamped-<name>.pdf` or `.png`) with the Sun-Stamp overlaid in the bottom-right corner for PDFs and Images.",
|
|
1535
2069
|
inputSchema: {
|
|
1536
2070
|
type: "object",
|
|
1537
2071
|
properties: {
|
|
@@ -1559,6 +2093,16 @@ const TOOLS = [
|
|
|
1559
2093
|
description:
|
|
1560
2094
|
"If true (default), automatically generates `reltime-stamped-<name>.pdf` or `.png` with the crisp 64-ray Sun-Stamp in the bottom-right corner when the file is a PDF or Image.",
|
|
1561
2095
|
},
|
|
2096
|
+
save_certificate_html: {
|
|
2097
|
+
type: "boolean",
|
|
2098
|
+
description:
|
|
2099
|
+
"If true (default), saves the 4-Plate Sovereign Cryptographic Provenance Certificate (`reltime-certificate-<filename>.html`) in the same folder as the file.",
|
|
2100
|
+
},
|
|
2101
|
+
open_certificate_in_browser: {
|
|
2102
|
+
type: "boolean",
|
|
2103
|
+
description:
|
|
2104
|
+
"If true, opens the generated 4-Plate Sovereign Cryptographic Provenance Certificate HTML in the system browser.",
|
|
2105
|
+
},
|
|
1562
2106
|
api_key: {
|
|
1563
2107
|
type: "string",
|
|
1564
2108
|
description: "Optional override for RELTIME_API_KEY (Autonomous Agent, Universal Anchor, or Enterprise Superhighway key).",
|
|
@@ -1655,7 +2199,7 @@ const TOOLS = [
|
|
|
1655
2199
|
{
|
|
1656
2200
|
name: "reltime_check_proof",
|
|
1657
2201
|
description:
|
|
1658
|
-
"Queries `GET /v1/proof/{hash}` to check the Bitcoin settlement status (Block Height, Block UTC Time, Bitcoin TXID, Merkle Root, and Merkle Inclusion Path) of an anchored hash. Optionally saves or updates the finalized `.json` Doomsday Proof receipt
|
|
2202
|
+
"Queries `GET /v1/proof/{hash}` to check the Bitcoin settlement status (Block Height, Block UTC Time, Bitcoin TXID, Merkle Root, and Merkle Inclusion Path) of an anchored hash. Optionally saves or updates the finalized `.json` Doomsday Proof receipt AND/OR generates the 4-Plate Sovereign Cryptographic Provenance Certificate HTML on demand.",
|
|
1659
2203
|
inputSchema: {
|
|
1660
2204
|
type: "object",
|
|
1661
2205
|
properties: {
|
|
@@ -1663,10 +2207,29 @@ const TOOLS = [
|
|
|
1663
2207
|
type: "string",
|
|
1664
2208
|
description: "The 64-character client_hash or t_index to verify.",
|
|
1665
2209
|
},
|
|
2210
|
+
file_path: {
|
|
2211
|
+
type: "string",
|
|
2212
|
+
description:
|
|
2213
|
+
"Optional local file path corresponding to the anchored hash (used to verify local custody/Passkey ownership and populate exact file name, size, and MIME type on the Provenance Certificate).",
|
|
2214
|
+
},
|
|
1666
2215
|
output_json_path: {
|
|
1667
2216
|
type: "string",
|
|
1668
2217
|
description: "Optional local file path to save the settled JSON Doomsday Proof receipt.",
|
|
1669
2218
|
},
|
|
2219
|
+
save_certificate_html: {
|
|
2220
|
+
type: "boolean",
|
|
2221
|
+
description:
|
|
2222
|
+
"If true, generates and saves the 4-Plate Sovereign Cryptographic Provenance Certificate (`reltime-certificate-<name>.html`) on demand.",
|
|
2223
|
+
},
|
|
2224
|
+
output_certificate_html_path: {
|
|
2225
|
+
type: "string",
|
|
2226
|
+
description: "Optional custom file path to save the 4-Plate Provenance Certificate HTML.",
|
|
2227
|
+
},
|
|
2228
|
+
open_certificate_in_browser: {
|
|
2229
|
+
type: "boolean",
|
|
2230
|
+
description:
|
|
2231
|
+
"If true, generates the 4-Plate Sovereign Cryptographic Provenance Certificate HTML and opens it in the system browser.",
|
|
2232
|
+
},
|
|
1670
2233
|
},
|
|
1671
2234
|
required: ["hash"],
|
|
1672
2235
|
},
|
|
@@ -1674,7 +2237,7 @@ const TOOLS = [
|
|
|
1674
2237
|
{
|
|
1675
2238
|
name: "reltime_account_status",
|
|
1676
2239
|
description:
|
|
1677
|
-
"Checks the remaining Hash Credits, tier, and lifetime usage of the configured Rel-Time API key (`GET /api/v1/account`). If no API key is configured yet, returns the 4 available Rel-Time Tiers (`universal` $3, `launch` $5/
|
|
2240
|
+
"Checks the remaining Hash Credits, tier, and lifetime usage of the configured Rel-Time API key (`GET /api/v1/account`). If no API key is configured yet, returns the 4 available Rel-Time Tiers (`universal` $3, `launch` $5/25, `standard` $50/500, `enterprise` $399/5,000) and payment options (`lightning` or `stripe`) so you can ask the user which tier they want to provision in chat.",
|
|
1678
2241
|
inputSchema: {
|
|
1679
2242
|
type: "object",
|
|
1680
2243
|
properties: {
|
|
@@ -1689,7 +2252,7 @@ const TOOLS = [
|
|
|
1689
2252
|
{
|
|
1690
2253
|
name: "reltime_provision_agent_key",
|
|
1691
2254
|
description:
|
|
1692
|
-
"Self-onboarding & Top-Up for all 4 Rel-Time Tiers via EITHER Bitcoin Lightning OR Stripe Card Checkout (`POST /v1/agent/invoice` & `POST /v1/agent/claim`). IMPORTANT:\n1. Before calling `create_invoice` for a new key, ask the user which tier AND payment method (`lightning` or `stripe`) they want:\n - **Universal Anchor (`pack: 'universal'`, $3 / anchor):** Priority 10-Minute Bitcoin Queue · Standard Mode (Biometric or Anonymous) · Supports `quantity` (default 1).\n - **Agent Launch Pack (`pack: 'launch'`, $5 /
|
|
2255
|
+
"Self-onboarding & Top-Up for all 4 Rel-Time Tiers via EITHER Bitcoin Lightning OR Stripe Card Checkout (`POST /v1/agent/invoice` & `POST /v1/agent/claim`). IMPORTANT:\n1. Before calling `create_invoice` for a new key, ask the user which tier AND payment method (`lightning` or `stripe`) they want:\n - **Universal Anchor (`pack: 'universal'`, $3 / anchor):** Priority 10-Minute Bitcoin Queue · Standard Mode (Biometric or Anonymous) · Supports `quantity` (default 1).\n - **Agent Launch Pack (`pack: 'launch'`, $5 / 25 Hashes, max 3 per key):** Priority 10-Minute Bitcoin Queue · Standard Mode · Includes Sun-Stamp, 1-Click Stamped Copy (.PDF/.PNG), 4-Plate Certificate, and .JSON Doomsday Proof.\n - **Autonomous Agents (`pack: 'standard'`, $50 / 500 Hashes):** Dynamic 6-Hour Batch Queue · Supports both Temporal Mode (`T_index` sub-second sequencing) and Standard Mode · Reloadable anytime (+500 credits / $50) with zero key rotation.\n - **Rel-Time Superhighway (`pack: 'enterprise'`, $399 / 5,000 Hashes):** Priority 10-Minute Bitcoin Queue · Supports Temporal Mode (`T_index`) & Standard Mode + Data Integrity Audit & Instant Tamper Detection.\n2. When `create_invoice` returns:\n - For **Lightning**: ALWAYS present BOTH the scannable QR code image (by calling Read on `qr_code_png_path`) AND the full, un-truncated `ln_invoice` (`bolt11`) string in a copyable code block on the VERY FIRST try!\n - For **Stripe**: The Stripe Checkout page opens automatically in the user's browser; also present the clickable `checkout_url` link and QR code (`qr_code_png_path`). Once paid, call `claim_invoice` with `invoice_id` (`cs_...`) to activate and save the key.",
|
|
1693
2256
|
inputSchema: {
|
|
1694
2257
|
type: "object",
|
|
1695
2258
|
properties: {
|
|
@@ -1703,7 +2266,7 @@ const TOOLS = [
|
|
|
1703
2266
|
type: "string",
|
|
1704
2267
|
enum: ["universal", "launch", "standard", "enterprise"],
|
|
1705
2268
|
description:
|
|
1706
|
-
"REQUIRED for 'create_invoice' after asking the user. Which tier the user selected: 'universal' ($3/anchor), 'launch' ($5 /
|
|
2269
|
+
"REQUIRED for 'create_invoice' after asking the user. Which tier the user selected: 'universal' ($3/anchor), 'launch' ($5 / 25 Hashes, max 3 per key), 'standard' ($50 / 500 Hashes), or 'enterprise' ($399 / 5,000 Hashes — Superhighway). If omitted on 'create_invoice', returns the 4 tier options so you can ask the user.",
|
|
1707
2270
|
},
|
|
1708
2271
|
payment_method: {
|
|
1709
2272
|
type: "string",
|
|
@@ -1738,7 +2301,7 @@ const TOOLS = [
|
|
|
1738
2301
|
{
|
|
1739
2302
|
name: "reltime_audit_trail",
|
|
1740
2303
|
description:
|
|
1741
|
-
"
|
|
2304
|
+
"SUPERHIGHWAY EXCLUSIVE ($399 / 5,000 Hashes): Data Integrity Audit, Instant Tamper Detection & Forensic Timechain Report (`GET /api/v1/account` + `GET /api/v1/account/history` + local SHA-256 cross-reference). Fetches the account's chronological anchor ledger, aggregates Bitcoin block settlements, VDF `T_index` ticks, and Corporate Hardware Passkey (`signer_public_key`) signatures, verifies a local file or entire folder bit-for-bit against the ledger (`verify_local_path`), and spins up a self-contained interactive HTML Forensic Audit Report (`reltime-audit-report-*.html`) in the user's browser.",
|
|
1742
2305
|
inputSchema: {
|
|
1743
2306
|
type: "object",
|
|
1744
2307
|
properties: {
|
|
@@ -1930,6 +2493,39 @@ async function executeTool(name, args = {}) {
|
|
|
1930
2493
|
stampedCopyResult = await stampLocalFileOptionA(filePath, svgContent, null, clientHash);
|
|
1931
2494
|
}
|
|
1932
2495
|
|
|
2496
|
+
// 4. Generate 4-Plate Sovereign Cryptographic Provenance Certificate HTML
|
|
2497
|
+
let savedCertificateHtmlPath = null;
|
|
2498
|
+
if (args.save_certificate_html !== false) {
|
|
2499
|
+
const certHtml = generateProvenanceCertificateHtml({
|
|
2500
|
+
fileName: path.basename(filePath),
|
|
2501
|
+
fileSize: formatBytes(fileBuffer.length),
|
|
2502
|
+
mimeType: inferMimeTypeFromFileName(path.basename(filePath)),
|
|
2503
|
+
originalFileHash,
|
|
2504
|
+
attestedHash: clientHash,
|
|
2505
|
+
signerPublicKey: passkeyCreds ? passkeyCreds.public_key_hex : null,
|
|
2506
|
+
anchorMode: data.anchor_mode || anchorMode,
|
|
2507
|
+
tIndex,
|
|
2508
|
+
vdfTicks: data.vdf_ticks || data.solar_ticks || 0,
|
|
2509
|
+
status: data.status || "pending_finality",
|
|
2510
|
+
blockHeight: data.settlement?.bitcoin_block_height || null,
|
|
2511
|
+
blockTimeUtc: data.settlement?.bitcoin_block_time
|
|
2512
|
+
? new Date(data.settlement.bitcoin_block_time * 1000).toISOString().replace("T", " ").slice(0, 19) + " UTC"
|
|
2513
|
+
: null,
|
|
2514
|
+
merkleProofCount: Array.isArray(data.settlement?.merkle_proof_path)
|
|
2515
|
+
? data.settlement.merkle_proof_path.length
|
|
2516
|
+
: null,
|
|
2517
|
+
txid: data.settlement?.bitcoin_txid || null,
|
|
2518
|
+
});
|
|
2519
|
+
savedCertificateHtmlPath = path.join(
|
|
2520
|
+
path.dirname(filePath),
|
|
2521
|
+
`reltime-certificate-${path.basename(filePath)}.html`
|
|
2522
|
+
);
|
|
2523
|
+
fs.writeFileSync(savedCertificateHtmlPath, certHtml, "utf8");
|
|
2524
|
+
if (args.open_certificate_in_browser) {
|
|
2525
|
+
openSystemBrowser(savedCertificateHtmlPath);
|
|
2526
|
+
}
|
|
2527
|
+
}
|
|
2528
|
+
|
|
1933
2529
|
return {
|
|
1934
2530
|
status: data.status || "pending_finality",
|
|
1935
2531
|
file_name: path.basename(filePath),
|
|
@@ -1945,6 +2541,7 @@ async function executeTool(name, args = {}) {
|
|
|
1945
2541
|
sun_stamp_svg_url: stampEndpointUrl,
|
|
1946
2542
|
saved_sun_stamp_svg_path: savedSvgPath,
|
|
1947
2543
|
saved_doomsday_proof_json_path: savedProofJsonPath,
|
|
2544
|
+
saved_certificate_html_path: savedCertificateHtmlPath,
|
|
1948
2545
|
stamped_copy: stampedCopyResult,
|
|
1949
2546
|
zero_knowledge_guarantee:
|
|
1950
2547
|
"File was hashed and stamped 100% locally on your machine; 0 bytes of file content were transmitted.",
|
|
@@ -2062,6 +2659,81 @@ async function executeTool(name, args = {}) {
|
|
|
2062
2659
|
fs.writeFileSync(jsonPath, JSON.stringify(out, null, 2), "utf8");
|
|
2063
2660
|
out.saved_json_path = jsonPath;
|
|
2064
2661
|
}
|
|
2662
|
+
|
|
2663
|
+
const wantsCert =
|
|
2664
|
+
Boolean(args.save_certificate_html) ||
|
|
2665
|
+
Boolean(args.output_certificate_html_path) ||
|
|
2666
|
+
Boolean(args.open_certificate_in_browser);
|
|
2667
|
+
|
|
2668
|
+
if (wantsCert && res.ok) {
|
|
2669
|
+
let fileName = "Zero-Knowledge Hash Payload";
|
|
2670
|
+
let fileSize = "Zero-Knowledge (32-Byte Digest)";
|
|
2671
|
+
let mimeType = "application/octet-stream (Zero-Knowledge)";
|
|
2672
|
+
let originalFileHash = data.original_file_hash || data.client_hash || hash;
|
|
2673
|
+
let targetDir = os.tmpdir();
|
|
2674
|
+
|
|
2675
|
+
if (args.file_path) {
|
|
2676
|
+
const resolvedFile = resolveLocalFilePath(args.file_path);
|
|
2677
|
+
if (fs.existsSync(resolvedFile)) {
|
|
2678
|
+
const stat = fs.statSync(resolvedFile);
|
|
2679
|
+
fileName = path.basename(resolvedFile);
|
|
2680
|
+
fileSize = formatBytes(stat.size);
|
|
2681
|
+
mimeType = inferMimeTypeFromFileName(fileName);
|
|
2682
|
+
targetDir = path.dirname(resolvedFile);
|
|
2683
|
+
if (!data.original_file_hash) {
|
|
2684
|
+
originalFileHash = crypto
|
|
2685
|
+
.createHash("sha256")
|
|
2686
|
+
.update(fs.readFileSync(resolvedFile))
|
|
2687
|
+
.digest("hex");
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
|
|
2692
|
+
const savedPasskey = loadSavedPasskey();
|
|
2693
|
+
if (data.signer_public_key) {
|
|
2694
|
+
out.passkey_custody_verified = Boolean(
|
|
2695
|
+
savedPasskey &&
|
|
2696
|
+
savedPasskey.public_key_hex.toLowerCase() === String(data.signer_public_key).toLowerCase()
|
|
2697
|
+
);
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2700
|
+
const certHtml = generateProvenanceCertificateHtml({
|
|
2701
|
+
fileName,
|
|
2702
|
+
fileSize,
|
|
2703
|
+
mimeType,
|
|
2704
|
+
originalFileHash,
|
|
2705
|
+
attestedHash: data.client_hash || hash,
|
|
2706
|
+
signerPublicKey: data.signer_public_key || null,
|
|
2707
|
+
anchorMode: data.anchor_mode || (data.vdf_ticks ? "temporal" : "standard"),
|
|
2708
|
+
tIndex: data.thermodynamic_proof || data.t_index || "PENDING VDF SNAPSHOT",
|
|
2709
|
+
vdfTicks: data.vdf_ticks || 0,
|
|
2710
|
+
status: data.status || "pending_finality",
|
|
2711
|
+
blockHeight: data.settlement?.bitcoin_block_height || null,
|
|
2712
|
+
blockTimeUtc: data.settlement?.bitcoin_block_time
|
|
2713
|
+
? new Date(data.settlement.bitcoin_block_time * 1000).toISOString().replace("T", " ").slice(0, 19) + " UTC"
|
|
2714
|
+
: null,
|
|
2715
|
+
merkleProofCount: Array.isArray(data.settlement?.merkle_proof_path)
|
|
2716
|
+
? data.settlement.merkle_proof_path.length
|
|
2717
|
+
: null,
|
|
2718
|
+
txid: data.settlement?.bitcoin_txid || null,
|
|
2719
|
+
});
|
|
2720
|
+
|
|
2721
|
+
const certPath = args.output_certificate_html_path
|
|
2722
|
+
? path.resolve(args.output_certificate_html_path)
|
|
2723
|
+
: path.join(
|
|
2724
|
+
targetDir,
|
|
2725
|
+
fileName !== "Zero-Knowledge Hash Payload"
|
|
2726
|
+
? `reltime-certificate-${fileName}.html`
|
|
2727
|
+
: `reltime-certificate-${hash.slice(0, 12)}.html`
|
|
2728
|
+
);
|
|
2729
|
+
fs.writeFileSync(certPath, certHtml, "utf8");
|
|
2730
|
+
out.saved_certificate_html_path = certPath;
|
|
2731
|
+
|
|
2732
|
+
if (args.open_certificate_in_browser) {
|
|
2733
|
+
openSystemBrowser(certPath);
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2065
2737
|
return out;
|
|
2066
2738
|
}
|
|
2067
2739
|
|
|
@@ -2111,6 +2783,35 @@ async function executeTool(name, args = {}) {
|
|
|
2111
2783
|
throw new Error(`Rel-Time Account error (${acctRes.status}): ${await acctRes.text()}`);
|
|
2112
2784
|
}
|
|
2113
2785
|
const acctData = await acctRes.json();
|
|
2786
|
+
const tierName = String(acctData.tier || "");
|
|
2787
|
+
const isSuperhighway =
|
|
2788
|
+
tierName.includes("Superhighway") ||
|
|
2789
|
+
tierName.includes("Enterprise") ||
|
|
2790
|
+
key.startsWith("rel_key_enterprise_");
|
|
2791
|
+
|
|
2792
|
+
if (!isSuperhighway) {
|
|
2793
|
+
return {
|
|
2794
|
+
status: "superhighway_upgrade_required",
|
|
2795
|
+
current_tier: tierName || "Standard / Agent",
|
|
2796
|
+
hash_credits: Number(acctData.hash_credits || 0),
|
|
2797
|
+
message:
|
|
2798
|
+
"Data Integrity Audit, Instant Tamper Detection, and Forensic Timechain Reports (`reltime_audit_trail`) are exclusive to the Rel-Time Superhighway ($399 / 5,000 Hashes) tier.",
|
|
2799
|
+
how_to_upgrade:
|
|
2800
|
+
"Ask the user if they would like to upgrade their current key to Rel-Time Superhighway ($399 / 5,000 Hashes) via Bitcoin Lightning (`lightning`) or Stripe Card (`stripe`), then call `reltime_provision_agent_key({ action: 'create_invoice', pack: 'enterprise', payment_method, reload_existing: true })`.",
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
if (Number(acctData.hash_credits || 0) <= 0) {
|
|
2805
|
+
return {
|
|
2806
|
+
status: "superhighway_renewal_required",
|
|
2807
|
+
current_tier: tierName,
|
|
2808
|
+
hash_credits: 0,
|
|
2809
|
+
message:
|
|
2810
|
+
"Your Rel-Time Superhighway key currently has 0 active Hash Credits remaining. Please renew your Superhighway cycle ($399 / 5,000 Hashes) to run Data Integrity Audits & Forensic Reports.",
|
|
2811
|
+
how_to_renew:
|
|
2812
|
+
"Ask the user if they would like to renew their Superhighway key via Bitcoin Lightning (`lightning`) or Stripe Card (`stripe`), then call `reltime_provision_agent_key({ action: 'create_invoice', pack: 'enterprise', payment_method, reload_existing: true })`.",
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2114
2815
|
|
|
2115
2816
|
const maxEntries = Math.min(500, Math.max(1, Number(args.limit) || 100));
|
|
2116
2817
|
const pageSize = Math.min(100, maxEntries);
|
|
@@ -2500,14 +3201,15 @@ async function executeTool(name, args = {}) {
|
|
|
2500
3201
|
|
|
2501
3202
|
if (!validPacks.includes(normalizedPack) || !validMethods.includes(normalizedMethod)) {
|
|
2502
3203
|
const missingNote = !validPacks.includes(normalizedPack)
|
|
2503
|
-
? "Please ask the user which Rel-Time Tier (`universal` $3, `launch` $5/
|
|
3204
|
+
? "Please ask the user which Rel-Time Tier (`universal` $3, `launch` $5/25, `standard` $50/500, or `enterprise` $399/5,000) AND which payment method (`lightning` or `stripe`) they would like to provision:"
|
|
2504
3205
|
: `The user selected pack '${normalizedPack}', but payment_method was not specified. Please ask the user whether they want to pay via Bitcoin Lightning ('lightning') or Stripe Card ('stripe') before calling create_invoice again:`;
|
|
2505
3206
|
return buildPackSelectionPrompt(missingNote);
|
|
2506
3207
|
}
|
|
2507
3208
|
|
|
2508
3209
|
const finalPack = normalizedPack === "superhighway" ? "enterprise" : normalizedPack;
|
|
2509
3210
|
const paymentMethod = normalizedMethod;
|
|
2510
|
-
const targetReloadKey =
|
|
3211
|
+
const targetReloadKey =
|
|
3212
|
+
args.api_key || ((args.reload_existing || finalPack === "launch") ? loadSavedApiKey() : "");
|
|
2511
3213
|
|
|
2512
3214
|
LAST_INVOICE_PACK = finalPack;
|
|
2513
3215
|
const reqBody = {
|
|
@@ -2610,7 +3312,8 @@ async function executeTool(name, args = {}) {
|
|
|
2610
3312
|
invoice_id: args.invoice_id,
|
|
2611
3313
|
pack: resolvedPack,
|
|
2612
3314
|
};
|
|
2613
|
-
const targetReloadKey =
|
|
3315
|
+
const targetReloadKey =
|
|
3316
|
+
args.api_key || ((args.reload_existing || resolvedPack === "launch") ? loadSavedApiKey() : "");
|
|
2614
3317
|
if (targetReloadKey && targetReloadKey.trim()) {
|
|
2615
3318
|
claimPayload.api_key = targetReloadKey.trim();
|
|
2616
3319
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rel-time/mcp-server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.11",
|
|
4
|
+
"mcpName": "io.github.relsun369-dev/rel-time",
|
|
4
5
|
"description": "Official Model Context Protocol (MCP) server for Rel-Time (rel-time.com) — Zero-Knowledge Bitcoin & VDF Provenance, Local File Hashing, and Sun-Stamp Generation for Claude, Cursor, Windsurf, and Antigravity.",
|
|
5
6
|
"main": "index.js",
|
|
6
7
|
"bin": {
|
|
@@ -9,11 +10,20 @@
|
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"index.js",
|
|
12
|
-
"README.md"
|
|
13
|
+
"README.md",
|
|
14
|
+
"server.json"
|
|
13
15
|
],
|
|
14
16
|
"scripts": {
|
|
15
17
|
"start": "node index.js"
|
|
16
18
|
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/relsun369-dev/reltime-mcp.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://rel-time.com",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/relsun369-dev/reltime-mcp/issues"
|
|
26
|
+
},
|
|
17
27
|
"keywords": [
|
|
18
28
|
"mcp",
|
|
19
29
|
"model-context-protocol",
|
package/server.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
|
|
3
|
+
"name": "io.github.relsun369-dev/rel-time",
|
|
4
|
+
"title": "Rel-Time Protocol (Bitcoin & VDF Provenance)",
|
|
5
|
+
"description": "Zero-knowledge Bitcoin Mainnet & VDF timestamping, Passkey signing, Sun-Stamps, and tamper audits.",
|
|
6
|
+
"websiteUrl": "https://rel-time.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"url": "https://github.com/relsun369-dev/reltime-mcp",
|
|
9
|
+
"source": "github"
|
|
10
|
+
},
|
|
11
|
+
"version": "1.2.11",
|
|
12
|
+
"packages": [
|
|
13
|
+
{
|
|
14
|
+
"registryType": "npm",
|
|
15
|
+
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
|
+
"identifier": "@rel-time/mcp-server",
|
|
17
|
+
"version": "1.2.11",
|
|
18
|
+
"transport": {
|
|
19
|
+
"type": "stdio"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|