217 lines
5.8 KiB
HTML
217 lines
5.8 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta http-equiv="refresh" content="3600" />
|
|
<title>Ledgr</title>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: #f9f9f9;
|
|
color: #333;
|
|
}
|
|
.container {
|
|
max-width: 800px;
|
|
margin: 50px auto;
|
|
padding: 20px;
|
|
background-color: #fff;
|
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
border-radius: 8px;
|
|
}
|
|
h2 {
|
|
color: #3498db;
|
|
}
|
|
input {
|
|
width: 95%;
|
|
padding: 10px;
|
|
margin: 10px 0;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
textarea {
|
|
width: 95%;
|
|
height: 100px;
|
|
padding: 10px;
|
|
margin: 10px 0;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
button {
|
|
padding: 10px 20px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
background-color: #3498db;
|
|
color: white;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
}
|
|
button:hover {
|
|
background-color: #2980b9;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container" id="root"></div>
|
|
|
|
<script type="module">
|
|
import {
|
|
html,
|
|
render,
|
|
Component
|
|
} from 'https://unpkg.com/htm/preact/standalone.module.js'
|
|
|
|
class App extends Component {
|
|
constructor() {
|
|
super()
|
|
const params = new URLSearchParams(window.location.search)
|
|
const token = params.get('token')
|
|
const status = ['Click Submit to call contract']
|
|
if (token) {
|
|
this.state = { fileContent: token, hue: '', status }
|
|
}
|
|
this.state = { fileContent: token, hue: '', status }
|
|
}
|
|
|
|
async componentDidMount() {
|
|
var file = './nostr.json'
|
|
var response = await fetch(file) // Fetch the file
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
`Failed to fetch text file ${file}: ${response.statusText}`
|
|
)
|
|
}
|
|
var txt = await response.text()
|
|
this.setState({ nostrContent: txt }) // Update state with file content
|
|
}
|
|
|
|
handleTextareaChange = event => {
|
|
this.setState({ fileContent: event.target.value })
|
|
}
|
|
|
|
handleHueChange = event => {
|
|
this.setState({ hue: event.target.value })
|
|
}
|
|
|
|
handleButtonClick = async () => {
|
|
const { fileContent, hue, status, nostrContent } = this.state
|
|
|
|
if (!fileContent || !hue) {
|
|
alert('Both fields must be filled out!')
|
|
return
|
|
}
|
|
|
|
status.push('Processing')
|
|
this.setState(status)
|
|
|
|
// Establish WebSocket connection and send the event
|
|
const relay = 'wss://npub.info'
|
|
const ws = new WebSocket(relay)
|
|
|
|
status.push('Opening socket to ' + relay)
|
|
this.setState(status)
|
|
|
|
ws.onopen = async () => {
|
|
status.push('connected to ' + relay)
|
|
this.setState(status)
|
|
const message = JSON.stringify({
|
|
content: 'sethue',
|
|
data: { fileContent, hue }
|
|
})
|
|
var nostr = JSON.parse(nostrContent)
|
|
var ev = await window.nostr.signEvent({
|
|
kind: 611,
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
tags: [
|
|
['proof', fileContent],
|
|
['p', nostr?.pubkey]
|
|
],
|
|
content: hue
|
|
})
|
|
|
|
var req = JSON.stringify(['EVENT', ev])
|
|
ws.send(req)
|
|
console.log('Message sent:', req)
|
|
status.push('message sent ' + req)
|
|
this.setState(status)
|
|
|
|
let now = new Date().getTime()
|
|
now = Math.floor(now / 1000.0)
|
|
let subscribe = `["REQ", "tail", {"kinds": [612, 613], "since": ${now} }]`
|
|
// if (qs.pubkey) {
|
|
// subscribe = `["REQ", "tail", { "authors": ["${qs.pubkey}"], "since": ${now} }]`
|
|
// }
|
|
console.log(subscribe)
|
|
status.push('subscribe ' + subscribe)
|
|
this.setState(status)
|
|
ws.send(subscribe)
|
|
|
|
// ws.close()
|
|
}
|
|
|
|
ws.onmessage = async event => {
|
|
const json = JSON.parse(event?.data)
|
|
if (json[0] === 'EOSE') {
|
|
console.log('EOSE')
|
|
return
|
|
}
|
|
if (event) {
|
|
status.push(event?.data)
|
|
this.setState(status)
|
|
console.log('event', event)
|
|
}
|
|
}
|
|
|
|
ws.onerror = error => {
|
|
console.error('WebSocket Error:', error)
|
|
}
|
|
|
|
// Additional actions can be taken here if needed
|
|
}
|
|
|
|
render() {
|
|
return html`
|
|
<div>
|
|
<h2>Enter Ecash Token</h2>
|
|
<textarea
|
|
value=${this.state.fileContent}
|
|
onInput=${this.handleTextareaChange}
|
|
></textarea>
|
|
|
|
<h2>Sethue</h2>
|
|
<input
|
|
type="number"
|
|
value=${this.state.hue}
|
|
onInput=${this.handleHueChange}
|
|
placeholder="Enter hue value (0-360)"
|
|
/>
|
|
|
|
<button onClick=${this.handleButtonClick}>Submit</button>
|
|
|
|
<pre>${this.state.stateContent}</pre>
|
|
|
|
<h2>Status</h2>
|
|
|
|
<pre>
|
|
|
|
|
|
${this.state.status
|
|
.map(status =>
|
|
typeof status === 'object' ? JSON.stringify(status) : status
|
|
)
|
|
.map(status => html`${status}<br />`)}
|
|
|
|
|
|
</pre
|
|
>
|
|
</div>
|
|
`
|
|
}
|
|
}
|
|
|
|
render(html`<${App} />`, document.getElementById('root'))
|
|
</script>
|
|
</body>
|
|
</html>
|