Skip to content

Commit

Permalink
Merge pull request lnbits#1 from motorina0/pegasus
Browse files Browse the repository at this point in the history
  • Loading branch information
fiatjaf committed Mar 12, 2023
2 parents e58d63f + c220d72 commit 62041b7
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 64 deletions.
53 changes: 37 additions & 16 deletions extension/content-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,34 @@ window.addEventListener('message', async message => {
// if we need the serial connection, handle it here (background.js doesn't have access)
switch (message.data.type) {
case 'getPublicKey': {
return callMethodOnDevice(METHOD_PUBLIC_KEY, [], connectionCallbacks)
const publicKey = await callMethodOnDevice(METHOD_PUBLIC_KEY, [], connectionCallbacks)
const xOnlyPublicKey = publicKey.substring(0, 64)
window.postMessage(
{
ext: 'horse',
id: message.data.id,
response: xOnlyPublicKey
},
'*'
)
break
}
case 'signEvent': {
let {event} = message.data.params

if (!event.pubkey) event.pubkey = callMethodOnDevice(METHOD_PUBLIC_KEY)
if (!event.pubkey) event.pubkey = (await callMethodOnDevice(METHOD_PUBLIC_KEY, [], connectionCallbacks)).substring(0, 64)
if (!event.id) event.id = getEventHash(event)
if (!validateEvent(event)) return {error: {message: 'invalid event'}}

event.sig = await callMethodOnDevice(METHOD_SIGN_MESSAGE, [event.id])
event.sig = await callMethodOnDevice(METHOD_SIGN_MESSAGE, [event.id], connectionCallbacks)
window.postMessage(
{
ext: 'horse',
id: message.data.id,
response: event
},
'*'
)
break
}
case 'nip04.encrypt': {
Expand Down Expand Up @@ -76,25 +94,28 @@ chrome.runtime.onMessage.addListener(async (req, sender) => {

const connectionCallbacks = {
onConnect() {
console.log('wqwewqel')
chrome.action.setBadgeBackgroundColor({color: 'green'})
chrome.action.setBadgeText({text: 'on'})
chrome.runtime.sendMessage({isConnected: true})
console.log('### chrome.action', chrome.action)
// chrome.action.setBadgeBackgroundColor({color: 'green'})
// chrome.action.setBadgeText({text: 'on'})
// chrome.runtime.sendMessage({isConnected: true})
},
onDisconnect() {
chrome.action.setBadgeText({text: ''})
chrome.runtime.sendMessage({isConnected: false})
console.log('### onDisconnect')
// chrome.action.setBadgeText({text: ''})
// chrome.runtime.sendMessage({isConnected: false})
},
onDone() {
chrome.action.setBadgeBackgroundColor({color: 'black'})
chrome.action.setBadgeText({text: 'done'})
chrome.runtime.sendMessage({isConnected: false})
console.log('### onDone')
// chrome.action.setBadgeBackgroundColor({color: 'black'})
// chrome.action.setBadgeText({text: 'done'})
// chrome.runtime.sendMessage({isConnected: false})
},
onError(error) {
chrome.action.setBadgeBackgroundColor({color: 'red'})
chrome.action.setBadgeText({text: 'err'})
chrome.runtime.sendMessage({isConnected: false})
chrome.runtime.sendMessage({serialError: error})
console.log('### onError', error)
// chrome.action.setBadgeBackgroundColor({color: 'red'})
// chrome.action.setBadgeText({text: 'err'})
// chrome.runtime.sendMessage({isConnected: false})
// chrome.runtime.sendMessage({serialError: error})
}
}

Expand Down
2 changes: 1 addition & 1 deletion extension/nostr-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ window.nostr = {
},

async signEvent(event) {
return this._call('signEvent', {event})
return await this._call('signEvent', {event})
},

async getRelays() {
Expand Down
99 changes: 52 additions & 47 deletions extension/serial.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ export const METHOD_SIGN_MESSAGE = '/sign-message'
export const METHOD_SHARED_SECRET = '/shared-secret'
export const METHOD_PUBLIC_KEY = '/public-key'

export const PUBLIC_METHODS = [METHOD_PUBLIC_KEY, METHOD_SIGN_MESSAGE, METHOD_SHARED_SECRET]

const sleep = ms => new Promise(r => setTimeout(r, ms))

let writer
let lastCommand = 0
let resolveCommand = () => {}
let resolveCommand = () => { }

export function isConnected() {
return !!writer
Expand All @@ -32,66 +34,69 @@ export async function callMethodOnDevice(method, params, opts) {
})
}

export async function initDevice({onConnect, onDisconnect, onError, onDone}) {
export async function initDevice({ onConnect, onDisconnect, onError, onDone }) {
return new Promise(async resolve => {
let port = await navigator.serial.requestPort()
let reader

port.addEventListener('connect', async event => {
;(async () => {
// reading responses
while (port && port.readable) {
const textDecoder = new window.TextDecoderStream()
port.readable.pipeTo(textDecoder.writable)
reader = textDecoder.readable.getReader()
const readStringUntil = readFromSerialPort(reader)

try {
while (true) {
const {value, done} = await readStringUntil('\n')
if (value) {
let {method, data} = parseResponse(value)
console.log('got', method, data)

if (method === METHOD_PING) {
// ignore ping responses
return
}

lastCommand = 0
resolveCommand(data)

const startSerialPortReading = async () => {
// reading responses
while (port && port.readable) {
const textDecoder = new window.TextDecoderStream()
port.readable.pipeTo(textDecoder.writable)
reader = textDecoder.readable.getReader()
const readStringUntil = readFromSerialPort(reader)

try {
while (true) {
const { value, done } = await readStringUntil('\n')
if (value) {
let { method, data } = parseResponse(value)
console.log('serial port data: ', method, data)

if (PUBLIC_METHODS.indexOf(method) === -1) {
// ignore /ping, /log responses
continue
}
if (done) return
onDone()

lastCommand = 0
resolveCommand(data)
}
} catch (error) {
console.warn(error)
onError(error.message)
if (done) return
onDone()
}
} catch (error) {
console.warn(error)
onError(error.message)
}
})()
}
}

await sleep(1000)
port.open({ baudRate: 9600 })

const textEncoder = new window.TextEncoderStream()
textEncoder.readable.pipeTo(port.writable)
writer = textEncoder.writable.getWriter()
// this `sleep()` is a hack, I know!!!
// but `port.onconnect` is never called. I don't know why!
await sleep(1000)
startSerialPortReading()

// send ping first
await sendCommand(METHOD_PING)
await sendCommand(METHOD_PING, [window.location.host])
const textEncoder = new window.TextEncoderStream()
textEncoder.readable.pipeTo(port.writable)
writer = textEncoder.writable.getWriter()

// send ping first
await sendCommand(METHOD_PING)
await sendCommand(METHOD_PING, [window.location.host])

onConnect()
resolve()

onConnect()
resolve()
})

port.addEventListener('disconnect', () => {
console.log('disconnected from device')
writer = null
onDisconnect()
})

port.open({baudRate: 9600})
})
}

Expand All @@ -113,19 +118,19 @@ function readFromSerialPort(reader) {
partialChunk = undefined
}
while (true) {
const {value, done} = await reader.read()
const { value, done } = await reader.read()
if (value) {
const values = value.split(separator)
// found one or more separators
if (values.length > 1) {
chunks.push(values.shift()) // first element
partialChunk = values.pop() // last element
fulliness = values // full lines
return {value: chunks.join('').trim(), done: false}
return { value: chunks.join('').trim(), done: false }
}
chunks.push(value)
}
if (done) return {value: chunks.join('').trim(), done: true}
if (done) return { value: chunks.join('').trim(), done: true }
}
}
return readStringUntil
Expand All @@ -135,5 +140,5 @@ function parseResponse(value) {
const method = value.split(' ')[0]
const data = value.substring(method.length).trim()

return {method, data}
return { method, data }
}

0 comments on commit 62041b7

Please sign in to comment.