Merge branch 'nostrify' into 'main'

Switch from NSpec to Nostrify

See merge request soapbox-pub/soapbox!3011
environments/review-main-yi2y9f/deployments/4585
Alex Gleason 2024-04-30 19:48:26 +00:00
commit 35354d16b5
10 zmienionych plików z 78 dodań i 104 usunięć

Wyświetl plik

@ -63,6 +63,7 @@
"@lexical/utils": "^0.14.2",
"@mkljczk/react-hotkeys": "^1.2.2",
"@noble/hashes": "^1.3.3",
"@nostrify/nostrify": "npm:@jsr/nostrify__nostrify",
"@popperjs/core": "^2.11.5",
"@reach/combobox": "^0.18.0",
"@reach/menu-button": "^0.18.0",
@ -73,7 +74,6 @@
"@sentry/browser": "^7.74.1",
"@sentry/react": "^7.74.1",
"@soapbox.pub/wasmboy": "^0.8.0",
"@soapbox/nspec": "npm:@jsr/soapbox__nspec",
"@soapbox/weblock": "npm:@jsr/soapbox__weblock",
"@tabler/icons": "^3.1.0",
"@tailwindcss/aspect-ratio": "^0.4.2",
@ -187,7 +187,7 @@
"vite-plugin-require": "^1.1.10",
"vite-plugin-static-copy": "^1.0.0",
"wicg-inert": "^3.1.1",
"zod": "^3.22.4"
"zod": "^3.23.5"
},
"devDependencies": {
"@formatjs/cli": "^6.2.0",

Wyświetl plik

@ -1,19 +1,8 @@
import { type NostrEvent } from '@soapbox/nspec';
import { NostrEvent, NostrConnectResponse, NSchema as n } from '@nostrify/nostrify';
import { useEffect } from 'react';
import { useNostr } from 'soapbox/contexts/nostr-context';
import { connectRequestSchema, nwcRequestSchema } from 'soapbox/schemas/nostr';
import { jsonSchema } from 'soapbox/schemas/utils';
/** NIP-46 [response](https://github.com/nostr-protocol/nips/blob/master/46.md#response-events-kind24133) content. */
interface NostrConnectResponse {
/** Request ID that this response is for. */
id: string;
/** Result of the call (this can be either a string or a JSON stringified object) */
result: string;
/** Error in string form, if any. Its presence indicates an error with the request. */
error?: string;
}
import { nwcRequestSchema } from 'soapbox/schemas/nostr';
function useSignerStream() {
const { relay, pubkey, signer } = useNostr();
@ -35,7 +24,7 @@ function useSignerStream() {
if (!relay || !pubkey || !signer) return;
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
const reqMsg = jsonSchema.pipe(connectRequestSchema).safeParse(decrypted);
const reqMsg = n.json().pipe(n.connectRequest()).safeParse(decrypted);
if (!reqMsg.success) {
console.warn(decrypted);
console.warn(reqMsg.error);
@ -104,7 +93,7 @@ function useSignerStream() {
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
const reqMsg = jsonSchema.pipe(nwcRequestSchema).safeParse(decrypted);
const reqMsg = n.json().pipe(nwcRequestSchema).safeParse(decrypted);
if (!reqMsg.success) {
console.warn(decrypted);
console.warn(reqMsg.error);

Wyświetl plik

@ -1,4 +1,4 @@
import { NRelay, NRelay1, NostrSigner } from '@soapbox/nspec';
import { NRelay, NRelay1, NostrSigner } from '@nostrify/nostrify';
import React, { createContext, useContext, useState, useEffect, useMemo } from 'react';
import { NKeys } from 'soapbox/features/nostr/keys';

Wyświetl plik

@ -18,8 +18,8 @@ const NostrRelays = () => {
const { relay, signer } = useNostr();
const { events } = useNostrReq(
account?.nostr
? [{ kinds: [10002], authors: [account?.nostr.pubkey], limit: 1 }]
account?.nostr?.pubkey
? [{ kinds: [10002], authors: [account.nostr.pubkey], limit: 1 }]
: [],
);

Wyświetl plik

@ -1,4 +1,4 @@
import { NSchema as n, NostrSigner, NSecSigner } from '@soapbox/nspec';
import { NSchema as n, NostrSigner, NSecSigner } from '@nostrify/nostrify';
import { WebLock } from '@soapbox/weblock';
import { getPublicKey, nip19 } from 'nostr-tools';
import { z } from 'zod';
@ -22,7 +22,7 @@ export class NKeyStorage implements ReadonlyMap<string, NostrSigner> {
WebLock.storages.lockKey(storageKey);
try {
const nsecs = new Set(this.#dataSchema().parse(data));
const nsecs = new Set(this.dataSchema().parse(data));
for (const nsec of nsecs) {
const { data: secretKey } = nip19.decode(nsec);
@ -34,8 +34,8 @@ export class NKeyStorage implements ReadonlyMap<string, NostrSigner> {
}
}
#dataSchema(): z.ZodType<`nsec1${string}`[]> {
return n.json().pipe(n.bech32('nsec').array());
private dataSchema(): z.ZodType<`nsec1${string}`[]> {
return n.json().pipe(n.bech32('nsec')).array() as z.ZodType<`nsec1${string}`[]>;
}
#syncStorage() {

Wyświetl plik

@ -1,4 +1,4 @@
import { NSet, NostrEvent, NostrFilter } from '@soapbox/nspec';
import { NSet, NostrEvent, NostrFilter } from '@nostrify/nostrify';
import isEqual from 'lodash/isEqual';
import { useEffect, useRef, useState } from 'react';

Wyświetl plik

@ -1,4 +1,4 @@
import { NSchema as n } from '@soapbox/nspec';
import { NSchema as n } from '@nostrify/nostrify';
import escapeTextContentForBrowser from 'escape-html';
import DOMPurify from 'isomorphic-dompurify';
import z from 'zod';

Wyświetl plik

@ -1,35 +1,9 @@
import { NSchema as n } from '@nostrify/nostrify';
import { verifyEvent } from 'nostr-tools';
import { z } from 'zod';
/** Schema to validate Nostr hex IDs such as event IDs and pubkeys. */
const nostrIdSchema = z.string().regex(/^[0-9a-f]{64}$/);
/** Nostr kinds are positive integers. */
const kindSchema = z.number().int().nonnegative();
/** Nostr event template schema. */
const eventTemplateSchema = z.object({
kind: kindSchema,
tags: z.array(z.array(z.string())),
content: z.string(),
created_at: z.number(),
});
/** Nostr event schema. */
const eventSchema = eventTemplateSchema.extend({
id: nostrIdSchema,
pubkey: nostrIdSchema,
sig: z.string(),
});
/** Nostr event schema that also verifies the event's signature. */
const signedEventSchema = eventSchema.refine(verifyEvent);
/** NIP-46 request content schema. */
const connectRequestSchema = z.object({
id: z.string(),
method: z.string(),
params: z.string().array(),
});
const signedEventSchema = n.event().refine(verifyEvent);
/** NIP-47 signer response. */
const nwcRequestSchema = z.object({
@ -39,4 +13,4 @@ const nwcRequestSchema = z.object({
}),
});
export { nostrIdSchema, kindSchema, eventSchema, signedEventSchema, connectRequestSchema, nwcRequestSchema };
export { signedEventSchema, nwcRequestSchema };

Wyświetl plik

@ -1,4 +1,4 @@
import type { NostrSigner } from '@soapbox/nspec';
import type { NostrSigner } from '@nostrify/nostrify';
declare global {
interface Window {

107
yarn.lock
Wyświetl plik

@ -1877,12 +1877,12 @@
dependencies:
"@noble/hashes" "1.3.2"
"@noble/curves@~1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.3.0.tgz#01be46da4fd195822dab821e72f71bf4aeec635e"
integrity sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==
"@noble/curves@~1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6"
integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==
dependencies:
"@noble/hashes" "1.3.3"
"@noble/hashes" "1.4.0"
"@noble/hashes@1.3.1":
version "1.3.1"
@ -1894,7 +1894,12 @@
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
"@noble/hashes@1.3.3", "@noble/hashes@^1.3.3", "@noble/hashes@~1.3.2":
"@noble/hashes@1.4.0", "@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426"
integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==
"@noble/hashes@^1.3.3":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699"
integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==
@ -1920,6 +1925,21 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@nostrify/nostrify@npm:@jsr/nostrify__nostrify":
version "0.17.1"
resolved "https://npm.jsr.io/~/10/@jsr/nostrify__nostrify/0.17.1.tgz#130487F4CF4715F1036A687E7EA819D3ADEC9B6F"
integrity sha512-+mUwudIJFSsnVD3+7PdFG+s27tOf9F1OROyRv7+cWoPWK9UnWlGFAQ50GIeDGYv9nd+gp8N7nu31r/cmqHmORw==
dependencies:
"@noble/hashes" "^1.4.0"
"@scure/base" "^1.1.6"
"@scure/bip32" "^1.4.0"
"@scure/bip39" "^1.3.0"
kysely "^0.27.3"
lru-cache "^10.2.0"
nostr-tools "^2.5.0"
websocket-ts "^2.1.5"
zod "^3.23.4"
"@popperjs/core@^2.11.5", "@popperjs/core@^2.9.2":
version "2.11.5"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
@ -2153,10 +2173,10 @@
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
"@scure/base@^1.1.5", "@scure/base@~1.1.4":
version "1.1.5"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.5.tgz#1d85d17269fe97694b9c592552dd9e5e33552157"
integrity sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==
"@scure/base@^1.1.6", "@scure/base@~1.1.6":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.6.tgz#8ce5d304b436e4c84f896e0550c83e4d88cb917d"
integrity sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==
"@scure/bip32@1.3.1":
version "1.3.1"
@ -2167,14 +2187,14 @@
"@noble/hashes" "~1.3.1"
"@scure/base" "~1.1.0"
"@scure/bip32@^1.3.3":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.3.tgz#a9624991dc8767087c57999a5d79488f48eae6c8"
integrity sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==
"@scure/bip32@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67"
integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==
dependencies:
"@noble/curves" "~1.3.0"
"@noble/hashes" "~1.3.2"
"@scure/base" "~1.1.4"
"@noble/curves" "~1.4.0"
"@noble/hashes" "~1.4.0"
"@scure/base" "~1.1.6"
"@scure/bip39@1.2.1":
version "1.2.1"
@ -2184,13 +2204,13 @@
"@noble/hashes" "~1.3.0"
"@scure/base" "~1.1.0"
"@scure/bip39@^1.2.2":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.2.tgz#f3426813f4ced11a47489cbcf7294aa963966527"
integrity sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==
"@scure/bip39@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3"
integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==
dependencies:
"@noble/hashes" "~1.3.2"
"@scure/base" "~1.1.4"
"@noble/hashes" "~1.4.0"
"@scure/base" "~1.1.6"
"@sentry-internal/tracing@7.74.1":
version "7.74.1"
@ -2276,20 +2296,6 @@
raf "^3.4.0"
responsive-gamepad "1.1.0"
"@soapbox/nspec@npm:@jsr/soapbox__nspec":
version "0.6.0"
resolved "https://npm.jsr.io/~/6/@jsr/soapbox__nspec/0.6.0.tgz#60A75BCDBEC1B76DFA91BEFDF5505CCB8ADDAD3B"
integrity sha512-HY+MssBjm532J9SAqLek8YGxBlEaXdT1Eek3bOWkq4uLJxipJhYkdQrW+NzXhfVvGZUt6YXBobeSqRQx1JFgkQ==
dependencies:
"@noble/hashes" "^1.3.3"
"@scure/base" "^1.1.5"
"@scure/bip32" "^1.3.3"
"@scure/bip39" "^1.2.2"
lru-cache "^10.2.0"
nostr-tools "^2.3.1"
websocket-ts "^2.1.5"
zod "^3.22.4"
"@soapbox/weblock@npm:@jsr/soapbox__weblock":
version "0.1.0"
resolved "https://npm.jsr.io/~/7/@jsr/soapbox__weblock/0.1.0.tgz#749AEE0872D23CC4E37366D5F0D092B87986C5E1"
@ -6153,6 +6159,11 @@ known-css-properties@^0.29.0:
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.29.0.tgz#e8ba024fb03886f23cb882e806929f32d814158f"
integrity sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==
kysely@^0.27.3:
version "0.27.3"
resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.27.3.tgz#6cc6c757040500b43c4ac596cdbb12be400ee276"
integrity sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA==
language-subtag-registry@~0.3.2:
version "0.3.21"
resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a"
@ -6396,9 +6407,9 @@ lowercase-keys@^2.0.0:
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lru-cache@^10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3"
integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==
version "10.2.2"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878"
integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==
lru-cache@^4.1.2:
version "4.1.5"
@ -6724,10 +6735,10 @@ nostr-tools@^2.3.0:
optionalDependencies:
nostr-wasm v0.1.0
nostr-tools@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-2.3.1.tgz#348d3c4aab0ab00716f93d6e2a72333d8c7da982"
integrity sha512-qjKx2C3EzwiQOe2LPSPyCnp07pGz1pWaWjDXcm+L2y2c8iTECbvlzujDANm3nJUjWL5+LVRUVDovTZ1a/DC4Bg==
nostr-tools@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-2.5.1.tgz#614d6aaf5c21df6b239d7ed42fdf77616a4621e7"
integrity sha512-bpkhGGAhdiCN0irfV+xoH3YP5CQeOXyXzUq7SYeM6D56xwTXZCPEmBlUGqFVfQidvRsoVeVxeAiOXW2c2HxoRQ==
dependencies:
"@noble/ciphers" "^0.5.1"
"@noble/curves" "1.2.0"
@ -9805,7 +9816,7 @@ zod@^3.21.0:
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.3.tgz#2fbc96118b174290d94e8896371c95629e87a060"
integrity sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==
zod@^3.22.4:
version "3.22.4"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.22.4.tgz#f31c3a9386f61b1f228af56faa9255e845cf3fff"
integrity sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==
zod@^3.23.4, zod@^3.23.5:
version "3.23.5"
resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.5.tgz#c7b7617d017d4a2f21852f533258d26a9a5ae09f"
integrity sha512-fkwiq0VIQTksNNA131rDOsVJcns0pfVUjHzLrNBiF/O/Xxb5lQyEXkhZWcJ7npWsYlvs+h0jFWXXy4X46Em1JA==