don't log privateKey, log nprofile
This commit is contained in:
parent
873f9e81d5
commit
b86de671e1
2 changed files with 101 additions and 1 deletions
88
src/custom-nip19.ts
Normal file
88
src/custom-nip19.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
This file contains functions that deal with encoding and decoding nprofiles,
|
||||||
|
but with he addition of bridge urls in the nprofile.
|
||||||
|
These functions are basically the same functions from nostr-tools package
|
||||||
|
but with some tweaks to allow for the bridge inclusion.
|
||||||
|
*/
|
||||||
|
import { bytesToHex, concatBytes, hexToBytes } from '@noble/hashes/utils';
|
||||||
|
import { bech32 } from 'bech32';
|
||||||
|
|
||||||
|
export const utf8Decoder = new TextDecoder('utf-8')
|
||||||
|
export const utf8Encoder = new TextEncoder()
|
||||||
|
|
||||||
|
|
||||||
|
export type CustomProfilePointer = {
|
||||||
|
pubkey: string
|
||||||
|
relays?: string[]
|
||||||
|
bridge?: string[] // one bridge
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type TLV = { [t: number]: Uint8Array[] }
|
||||||
|
|
||||||
|
|
||||||
|
const encodeTLV = (tlv: TLV): Uint8Array => {
|
||||||
|
const entries: Uint8Array[] = []
|
||||||
|
|
||||||
|
Object.entries(tlv)
|
||||||
|
/*
|
||||||
|
the original function does a reverse() here,
|
||||||
|
but here it causes the nprofile string to be different,
|
||||||
|
even though it would still decode to the correct original inputs
|
||||||
|
*/
|
||||||
|
//.reverse()
|
||||||
|
.forEach(([t, vs]) => {
|
||||||
|
vs.forEach(v => {
|
||||||
|
const entry = new Uint8Array(v.length + 2)
|
||||||
|
entry.set([parseInt(t)], 0)
|
||||||
|
entry.set([v.length], 1)
|
||||||
|
entry.set(v, 2)
|
||||||
|
entries.push(entry)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return concatBytes(...entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const encodeNprofile = (profile: CustomProfilePointer): string => {
|
||||||
|
const data = encodeTLV({
|
||||||
|
0: [hexToBytes(profile.pubkey)],
|
||||||
|
1: (profile.relays || []).map(url => utf8Encoder.encode(url)),
|
||||||
|
2: (profile.bridge || []).map(url => utf8Encoder.encode(url))
|
||||||
|
});
|
||||||
|
const words = bech32.toWords(data)
|
||||||
|
return bech32.encode("nprofile", words, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseTLV = (data: Uint8Array): TLV => {
|
||||||
|
const result: TLV = {}
|
||||||
|
let rest = data
|
||||||
|
while (rest.length > 0) {
|
||||||
|
const t = rest[0]
|
||||||
|
const l = rest[1]
|
||||||
|
const v = rest.slice(2, 2 + l)
|
||||||
|
rest = rest.slice(2 + l)
|
||||||
|
if (v.length < l) throw new Error(`not enough data to read on TLV ${t}`)
|
||||||
|
result[t] = result[t] || []
|
||||||
|
result[t].push(v)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
export const decodeNprofile = (nprofile: string): CustomProfilePointer => {
|
||||||
|
const { prefix, words } = bech32.decode(nprofile, 5000)
|
||||||
|
if (prefix !== "nprofile") {
|
||||||
|
throw new Error ("Expected nprofile prefix");
|
||||||
|
}
|
||||||
|
const data = new Uint8Array(bech32.fromWords(words))
|
||||||
|
|
||||||
|
const tlv = parseTLV(data);
|
||||||
|
if (!tlv[0]?.[0]) throw new Error('missing TLV 0 for nprofile')
|
||||||
|
if (tlv[0][0].length !== 32) throw new Error('TLV 0 should be 32 bytes')
|
||||||
|
|
||||||
|
return {
|
||||||
|
pubkey: bytesToHex(tlv[0][0]),
|
||||||
|
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : [],
|
||||||
|
bridge: tlv[2] ? tlv[2].map(d => utf8Decoder.decode(d)): []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
import { SimplePool, Sub, Event, UnsignedEvent, getEventHash, finishEvent, relayInit } from './tools/index.js'
|
import { SimplePool, Sub, Event, UnsignedEvent, getEventHash, finishEvent, relayInit } from './tools/index.js'
|
||||||
import { encryptData, decryptData, getSharedSecret, decodePayload, encodePayload } from './nip44.js'
|
import { encryptData, decryptData, getSharedSecret, decodePayload, encodePayload } from './nip44.js'
|
||||||
import { getLogger } from '../helpers/logger.js'
|
import { getLogger } from '../helpers/logger.js'
|
||||||
|
import { encodeNprofile } from '../../custom-nip19.js'
|
||||||
const handledEvents: string[] = [] // TODO: - big memory leak here, add TTL
|
const handledEvents: string[] = [] // TODO: - big memory leak here, add TTL
|
||||||
type AppInfo = { appId: string, publicKey: string, privateKey: string, name: string }
|
type AppInfo = { appId: string, publicKey: string, privateKey: string, name: string }
|
||||||
export type SendData = { type: "content", content: string, pub: string } | { type: "event", event: UnsignedEvent }
|
export type SendData = { type: "content", content: string, pub: string } | { type: "event", event: UnsignedEvent }
|
||||||
|
|
@ -88,7 +89,18 @@ export default class Handler {
|
||||||
eventCallback: (event: NostrEvent) => void
|
eventCallback: (event: NostrEvent) => void
|
||||||
constructor(settings: NostrSettings, eventCallback: (event: NostrEvent) => void) {
|
constructor(settings: NostrSettings, eventCallback: (event: NostrEvent) => void) {
|
||||||
this.settings = settings
|
this.settings = settings
|
||||||
console.log(settings)
|
console.log(
|
||||||
|
{
|
||||||
|
...settings,
|
||||||
|
apps: settings.apps.map(app => {
|
||||||
|
const { privateKey, ...rest } = app;
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
nprofile: encodeNprofile({ pubkey: rest.publicKey, relays: settings.relays })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
this.eventCallback = eventCallback
|
this.eventCallback = eventCallback
|
||||||
this.settings.apps.forEach(app => {
|
this.settings.apps.forEach(app => {
|
||||||
this.apps[app.publicKey] = app
|
this.apps[app.publicKey] = app
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue