fix: type errors

This commit is contained in:
Ricardo Arturo Cabral Mejía
2022-12-21 01:28:42 -05:00
parent f3c801e503
commit f3097983a0
14 changed files with 61 additions and 47 deletions

View File

@@ -15,3 +15,4 @@ Dockerfile
*.md
.nostr
postgresql.conf
test/integration/docker-compose.yml

View File

@@ -53,4 +53,4 @@ RUN npm install --omit=dev --quiet
USER 1000:1000
CMD ["node", "src/index.js"]
CMD ["node", "src/index.js"]

View File

@@ -10,11 +10,11 @@ ENV DB_MAX_POOL_SIZE=2
ENV REDIS_HOST=cache-test
ENV REDIS_PORT=6379
ENV REDIS_USER=default
ENV REDIS_PASSWORD=nostr_ts_relay
ENV REDIS_PASSWORD=nostr_ts_relay_test
WORKDIR /code
COPY ["package.json", "settings.sample.json", "package-lock.json", ".nycrc.json", ".mocharc.js", "cucumber.js", "tsconfig.json", "knexfile.js", "./"]
COPY ["package.json", "package-lock.json", "./"]
RUN npm install --quiet

View File

@@ -3,7 +3,7 @@ services:
build: .
container_name: nostr-ts-relay
environment:
PORT: 8008
RELAY_PORT: 8008
NOSTR_CONFIG_DIR: /home/node/
DB_HOST: db
DB_PORT: 5432

View File

@@ -19,7 +19,7 @@ export class AppWorker implements IRunnable {
}
public run(): void {
const port = Number(process.env.PORT) || 8008
const port = Number(process.env.RELAY_PORT) || 8008
this.adapter.listen(port)
}

4
src/cache/client.ts vendored
View File

@@ -6,12 +6,14 @@ export const getCacheConfig = (): RedisClientOptions => ({
password: process.env.REDIS_PASSWORD,
})
let instance: CacheClient = undefined
let instance: CacheClient | undefined = undefined
export const getCacheClient = (): CacheClient => {
if (!instance) {
const config = getCacheConfig()
console.log(config)
instance = createClient(config)
}

View File

@@ -13,11 +13,11 @@ export const workerFactory = (): AppWorker => {
const dbClient = getDbClient()
const eventRepository = new EventRepository(dbClient)
// deepcode ignore HttpToHttps: <please specify a reason of ignoring this>
// deepcode ignore HttpToHttps: we use proxies
const server = http.createServer()
const webSocketServer = new WebSocketServer({
server,
maxPayload: 1024 * 1024,
maxPayload: 102400, // 0.1 MB
})
const adapter = new WebSocketServerAdapter(
server,

View File

@@ -1,8 +1,8 @@
import * as secp256k1 from '@noble/secp256k1'
import { applySpec, converge, curry, mergeLeft, nth, omit, pipe, prop, reduceBy } from 'ramda'
import { CanonicalEvent, Event } from '../@types/event'
import { EventId, Pubkey } from '../@types/base'
import { CanonicalEvent, DBEvent, Event } from '../@types/event'
import { EventId, Pubkey, Tag } from '../@types/base'
import { EventKinds, EventTags } from '../constants/base'
import { fromBuffer } from './transform'
import { getLeadingZeroBits } from './proof-of-work'
@@ -10,7 +10,7 @@ import { isGenericTagQuery } from './filter'
import { RuneLike } from './runes/rune-like'
import { SubscriptionFilter } from '../@types/subscription'
export const serializeEvent = (event: Partial<Event>): CanonicalEvent => [
export const serializeEvent = (event: Event): CanonicalEvent => [
0,
event.pubkey,
event.created_at,
@@ -19,18 +19,18 @@ export const serializeEvent = (event: Partial<Event>): CanonicalEvent => [
event.content,
]
export const toNostrEvent = applySpec({
id: pipe(prop('event_id'), fromBuffer),
kind: prop('event_kind'),
pubkey: pipe(prop('event_pubkey'), fromBuffer),
created_at: prop('event_created_at'),
content: prop('event_content'),
tags: prop('event_tags'),
sig: pipe(prop('event_signature'), fromBuffer),
export const toNostrEvent: (event: DBEvent) => Event = applySpec({
id: pipe(prop('event_id') as () => Buffer, fromBuffer),
kind: prop('event_kind') as () => number,
pubkey: pipe(prop('event_pubkey') as () => Buffer, fromBuffer),
created_at: prop('event_created_at') as () => number,
content: prop('event_content') as () => string,
tags: prop('event_tags') as () => Tag[],
sig: pipe(prop('event_signature') as () => Buffer, fromBuffer),
})
export const isEventMatchingFilter = (filter: SubscriptionFilter) => (event: Event): boolean => {
const startsWith = (input: string) => (prefix) => input.startsWith(prefix)
const startsWith = (input: string) => (prefix: string) => input.startsWith(prefix)
// NIP-01: Basic protocol flow description
@@ -58,6 +58,9 @@ export const isEventMatchingFilter = (filter: SubscriptionFilter) => (event: Eve
) {
if (isDelegatedEvent(event)) {
const delegation = event.tags.find((tag) => tag[0] === EventTags.Delegation)
if (typeof delegation === 'undefined') {
return false
}
if (!filter.authors.some(startsWith(delegation[1]))) {
return false
@@ -119,10 +122,10 @@ export const isDelegatedEventValid = async (event: Event): Promise<boolean> => {
omit(['tags']),
pipe(
prop('tags') as any,
reduceBy(
reduceBy<EventTags, string[]>(
(acc, tag) => ([...acc, tag[1]]),
[],
nth(0),
nth(0) as any,
),
),
],

View File

@@ -2,7 +2,7 @@ import { IAlternative } from '../../@types/runes'
const punctuations = /[!"#$%&'()*+-./:;<=>?@[\\\]^`{|}~]/
const hasPunctuation = (input) => punctuations.test(input)
const hasPunctuation = (input: string) => punctuations.test(input)
// Reference: https://github.com/rustyrussell/runes/blob/master/runes/runes.py

View File

@@ -4,6 +4,7 @@ services:
context: ../../
dockerfile: Dockerfile.test
environment:
RELAY_PORT: 18808
DB_HOST: db-test
DB_PORT: 5432
DB_NAME: nostr_ts_relay_test
@@ -17,10 +18,14 @@ services:
REDIS_PASSWORD: nostr_ts_relay_test
NOSTR_CONFIG_DIR: /code
volumes:
- ../../package.json:/code/package.json
- ../../settings.sample.json:/code/settings.sample.json
- ../../src:/code/src
- ../../test:/code/test
- ../../test/integration:/code/test/integration
- ../../cucumber.js:/code/cucumber.js
- ../../.coverage:/code/.coverage
- ../../.test-reports:/code/.test-reports
- ../../tsconfig.json:/code/tsconfig.json
working_dir: /code
depends_on:
cache-test:

View File

@@ -1,6 +1,6 @@
import * as secp256k1 from '@noble/secp256k1'
import { createHash, createHmac, Hash } from 'crypto'
import WebSocket, { RawData } from 'ws'
import { createHmac } from 'crypto'
import { Event } from '../../../src/@types/event'
import { MessageType } from '../../../src/@types/messages'
@@ -8,6 +8,9 @@ import { serializeEvent } from '../../../src/utils/event'
import { SubscriptionFilter } from '../../../src/@types/subscription'
secp256k1.utils.sha256Sync = (...messages: Uint8Array[]) =>
messages.reduce((hash: Hash, message: Uint8Array) => hash.update(message), createHash('sha256')).digest()
export async function connect(_name: string) {
const host = 'ws://localhost:18808'
const ws = new WebSocket(host)
@@ -35,17 +38,18 @@ export async function createEvent(input: Partial<Event>, privkey: any): Promise<
tags: input.tags ?? [],
} as any
const id = Buffer.from(
await secp256k1.utils.sha256(
Buffer.from(JSON.stringify(serializeEvent(event)))
)
).toString('hex')
const id = createHash('sha256').update(
Buffer.from(JSON.stringify(serializeEvent(event)))
).digest().toString('hex')
const sig = Buffer.from(
await secp256k1.schnorr.sign(id, privkey)
secp256k1.schnorr.signSync(id, privkey)
).toString('hex')
return { id, ...event, sig }
event.id = id
event.sig = sig
return event
}
export function createIdentity(name: string) {
@@ -73,7 +77,7 @@ export async function createSubscription(
...subscriptionFilters,
])
ws.send(message, (error: Error) => {
ws.send(message, (error?: Error) => {
if (error) {
reject(error)
return
@@ -157,7 +161,7 @@ export async function waitForEventCount(
count = 1,
eose = false,
): Promise<Event[]> {
const events = []
const events: Event[] = []
return new Promise((resolve, reject) => {
ws.on('message', onMessage)

View File

@@ -8,6 +8,7 @@ import {
When,
World,
} from '@cucumber/cucumber'
import { assocPath } from 'ramda'
import WebSocket from 'ws'
import { connect, createIdentity, createSubscription } from './helpers'
@@ -25,13 +26,14 @@ let dbClient: DatabaseClient
let cacheClient: CacheClient
BeforeAll({ timeout: 6000 }, async function () {
process.env.PORT = '18808'
process.env.RELAY_PORT = '18808'
cacheClient = getCacheClient()
dbClient = getDbClient()
await dbClient.raw('SELECT 1=1')
const limits = SettingsStatic.createSettings().limits
limits.event.createdAt.maxPositiveDelta = 0
const { limits } = SettingsStatic.createSettings()
assocPath(['event', 'createdAt', 'maxPositiveDelta'], 0)(limits)
worker = workerFactory()
worker.run()
@@ -56,18 +58,18 @@ Before(async function () {
After(async function () {
this.parameters.events = {}
this.parameters.subscriptions = {}
Object.values(this.parameters.clients).forEach((ws: WebSocket) => {
for (const ws of Object.values(this.parameters.clients as Record<string, WebSocket>)) {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.close()
}
})
}
this.parameters.clients = {}
const dbClient = getDbClient()
await Promise.all(
Object.values(this.parameters.identities)
.map(async (identity: { pubkey: string }) => dbClient('events').where({ event_pubkey: Buffer.from(identity.pubkey, 'hex') }).del())
)
for (const identity of Object.values(this.parameters.identities as Record<string, { pubkey: string }>)) {
await dbClient('events').where({ event_pubkey: Buffer.from(identity.pubkey, 'hex') }).del()
}
this.parameters.identities = {}
})

View File

@@ -68,7 +68,7 @@ describe('messageHandlerFactory', () => {
})
it('throws when given an invalid message', () => {
message = []
message = [] as any
expect(() => factory([message, adapter])).to.throw(Error, 'Unknown message type: undefined')
})

View File

@@ -19,9 +19,6 @@
"esModuleInterop": true,
"lib": ["ESNext"]
},
"ts-node": {
"transpileOnly": true
},
"include": [
"src/**/*.ts",
"test/**/*.ts"