1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+ < head >
4+ < meta charset ="UTF-8 ">
5+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > Attestation Created - attest.ink</ title >
7+ < meta name ="description " content ="Your AI attestation has been created successfully ">
8+ < link rel ="icon " type ="image/svg+xml " href ="/assets/logo/favicon.svg ">
9+ < link rel ="icon " type ="image/x-icon " href ="/assets/favicon.ico ">
10+ < link rel ="manifest " href ="/assets/site.webmanifest ">
11+ < meta name ="theme-color " content ="#111827 ">
12+ < link rel ="stylesheet " href ="/static/style.css ">
13+ < link rel ="stylesheet " href ="/static/badge-styles.css ">
14+ < script src ="/static/ai-models.js?v=2 "> </ script >
15+ < script >
16+ // Prevent theme flicker by setting theme before render
17+ ( function ( ) {
18+ const saved = localStorage . getItem ( 'theme' ) ;
19+ let theme = 'light' ;
20+ if ( saved ) {
21+ theme = saved ;
22+ } else if ( window . matchMedia && window . matchMedia ( '(prefers-color-scheme: dark)' ) . matches ) {
23+ theme = 'dark' ;
24+ } else {
25+ const hour = new Date ( ) . getHours ( ) ;
26+ if ( hour >= 18 || hour < 6 ) {
27+ theme = 'dark' ;
28+ }
29+ }
30+ document . documentElement . setAttribute ( 'data-theme' , theme ) ;
31+ } ) ( ) ;
32+ </ script >
33+ </ head >
34+ < body >
35+ < button class ="theme-toggle " id ="theme-toggle " aria-label ="Toggle theme "> D</ button >
36+ < div class ="container ">
37+ < nav >
38+ < div class ="nav-inner ">
39+ < a href ="/ " class ="logo ">
40+ < img src ="/assets/logo/circular-2-ai.svg " alt ="attest.ink logo ">
41+ < span > attest.ink</ span >
42+ </ a >
43+ < ul >
44+ < li > < a href ="/create/ "> Create</ a > </ li >
45+ < li > < a href ="/verify/ "> Verify</ a > </ li >
46+ < li class ="dropdown ">
47+ < span class ="dropdown-toggle "> More</ span >
48+ < div class ="dropdown-menu ">
49+ < a href ="/protocol/ "> Protocol</ a >
50+ < a href ="/showcase/ "> Badges</ a >
51+ < a href ="/examples/ "> Examples</ a >
52+ < a href ="/developers/ "> Developers</ a >
53+ < a href ="/faq.html "> FAQ</ a >
54+ < a href ="https://github.com/attestation-ink " target ="_blank "> GitHub</ a >
55+ </ div >
56+ </ li >
57+ </ ul >
58+ </ div >
59+ </ nav >
60+
61+ < main >
62+ < div id ="result-section " style ="margin-top: 40px; ">
63+ < h2 > Attestation Created</ h2 >
64+
65+ < pre id ="attestation-json "> </ pre >
66+
67+ < div style ="margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap; ">
68+ < button id ="download-json " class ="btn btn-secondary "> Download JSON</ button >
69+ < button id ="copy-json " class ="btn btn-secondary "> Copy JSON</ button >
70+ < a href ="/verify/ " id ="verify-link " class ="btn btn-secondary "> Verify Attestation</ a >
71+ < a href ="/create/ " class ="btn "> Create Another</ a >
72+ </ div >
73+
74+ < h3 style ="margin-top: 40px; "> Share Your Attestation</ h3 >
75+
76+ < div id ="badge-section ">
77+ < div id ="badge-preview " style ="margin: 20px 0; padding: 20px; background: var(--bg-panel); border: 1px solid var(--border-color); border-radius: 8px; text-align: center; "> </ div >
78+
79+ < div id ="embed-section ">
80+ < h4 > Option 1: Embed Badge</ h4 >
81+ < p style ="margin-bottom: 10px; "> Self-contained HTML with full attestation data (works offline):</ p >
82+ < pre id ="badge-embed-code "> </ pre >
83+ < button id ="copy-embed-code " class ="btn btn-secondary "> Copy Embed Code</ button >
84+ </ div >
85+
86+ < div id ="link-section " style ="margin-top: 20px; ">
87+ < h4 > Option 2: Direct Links</ h4 >
88+ < div style ="margin-bottom: 15px; ">
89+ < p style ="margin-bottom: 5px; "> < strong > Short URL</ strong > (requires server or localStorage):</ p >
90+ < pre id ="badge-link-code " style ="padding: 10px; background: var(--bg-panel); border: 1px solid var(--border-color); border-radius: 4px; overflow-x: auto; font-size: 14px; color: var(--text-primary); min-height: 20px; "> </ pre >
91+ < button id ="copy-link-code " class ="btn btn-secondary "> Copy Short URL</ button >
92+ </ div >
93+ < div >
94+ < p style ="margin-bottom: 5px; "> < strong > Full Data URL</ strong > (works offline, self-contained):</ p >
95+ < pre id ="badge-data-url " style ="padding: 10px; background: var(--bg-panel); border: 1px solid var(--border-color); border-radius: 4px; overflow-x: auto; font-size: 14px; color: var(--text-primary); min-height: 20px; word-wrap: break-word; white-space: pre-wrap; "> </ pre >
96+ < button id ="copy-data-url " class ="btn btn-secondary "> Copy Data URL</ button >
97+ </ div >
98+ </ div >
99+
100+ < div id ="api-section " style ="margin-top: 20px; ">
101+ < h4 > Option 3: API / Automation</ h4 >
102+ < p style ="margin-bottom: 10px; "> Create attestations programmatically using curl:</ p >
103+ < pre id ="api-curl-command " style ="font-size: 0.9em; "> </ pre >
104+ < button id ="copy-api-command " class ="btn btn-secondary "> Copy curl Command</ button >
105+ </ div >
106+
107+ < div id ="latex-section " style ="display: none; margin-top: 20px; ">
108+ < h4 > LaTeX Code</ h4 >
109+ < p > Basic version:</ p >
110+ < pre id ="latex-code " style ="font-size: 0.9em; "> </ pre >
111+ < button id ="copy-latex-code " class ="btn btn-secondary "> Copy LaTeX Code</ button >
112+
113+ < p style ="margin-top: 15px; "> Extended version with footnote:</ p >
114+ < pre id ="latex-extended " style ="font-size: 0.9em; "> </ pre >
115+ < button id ="copy-latex-extended " class ="btn btn-secondary "> Copy Extended LaTeX</ button >
116+ </ div >
117+
118+ < div id ="markdown-section " style ="display: none; margin-top: 20px; ">
119+ < h4 > Markdown Code</ h4 >
120+ < pre id ="markdown-code " style ="font-size: 0.9em; "> </ pre >
121+ < button id ="copy-markdown-code " class ="btn btn-secondary "> Copy Markdown</ button >
122+ </ div >
123+ </ div >
124+ </ div >
125+ </ main >
126+
127+ < footer >
128+ < p > A public-benefit, open-source AI integrity protocol | < a href ="/protocol/ "> Learn about the protocol</ a > </ p >
129+ </ footer >
130+ </ div >
131+ < script src ="/static/script.js?v=2 "> </ script >
132+ < script src ="/static/global-footer.js "> </ script >
133+ < script src ="/attestation-result.js "> </ script >
134+ < script >
135+ // Get attestation from URL parameters or localStorage
136+ const urlParams = new URLSearchParams ( window . location . search ) ;
137+ const attestationId = urlParams . get ( 'id' ) ;
138+
139+ if ( ! attestationId ) {
140+ alert ( 'No attestation ID provided' ) ;
141+ window . location . href = '/create/' ;
142+ } else {
143+ // Try to load from localStorage
144+ const storedAttestation = localStorage . getItem ( `attestation-${ attestationId } ` ) ;
145+ if ( ! storedAttestation ) {
146+ alert ( 'Attestation not found. It may have been created in a different browser.' ) ;
147+ window . location . href = '/create/' ;
148+ } else {
149+ const attestation = JSON . parse ( storedAttestation ) ;
150+ window . currentAttestation = attestation ;
151+
152+ // Display the attestation
153+ document . getElementById ( 'attestation-json' ) . textContent = JSON . stringify ( attestation , null , 2 ) ;
154+
155+ // Update verify link
156+ document . getElementById ( 'verify-link' ) . href = `/verify/?id=${ attestation . id } ` ;
157+
158+ // Generate all the display elements
159+ generateAttestationDisplay ( attestation ) ;
160+
161+ // Initialize copy button handlers
162+ initializeCopyButtons ( ) ;
163+ }
164+ }
165+
166+ // Copy event listeners
167+ document . getElementById ( 'download-json' ) . addEventListener ( 'click' , function ( ) {
168+ const blob = new Blob ( [ JSON . stringify ( window . currentAttestation , null , 2 ) ] , { type : 'application/json' } ) ;
169+ const url = URL . createObjectURL ( blob ) ;
170+ const a = document . createElement ( 'a' ) ;
171+ a . href = url ;
172+ a . download = `attestation-${ window . currentAttestation . id } .json` ;
173+ document . body . appendChild ( a ) ;
174+ a . click ( ) ;
175+ document . body . removeChild ( a ) ;
176+ URL . revokeObjectURL ( url ) ;
177+ } ) ;
178+
179+ document . getElementById ( 'copy-json' ) . addEventListener ( 'click' , async function ( ) {
180+ try {
181+ await navigator . clipboard . writeText ( JSON . stringify ( window . currentAttestation , null , 2 ) ) ;
182+ this . textContent = 'Copied!' ;
183+ setTimeout ( ( ) => {
184+ this . textContent = 'Copy JSON' ;
185+ } , 2000 ) ;
186+ } catch ( err ) {
187+ alert ( 'Failed to copy JSON' ) ;
188+ }
189+ } ) ;
190+ </ script >
191+ </ body >
192+ </ html >
0 commit comments