Nostr: sign events with NIP-46
This commit is contained in:
parent
c2a8044aa4
commit
1011be5333
13 changed files with 158 additions and 70 deletions
|
@ -173,11 +173,6 @@ const connectTimelineStream = (
|
||||||
case 'marker':
|
case 'marker':
|
||||||
dispatch({ type: MARKER_FETCH_SUCCESS, marker: JSON.parse(data.payload) });
|
dispatch({ type: MARKER_FETCH_SUCCESS, marker: JSON.parse(data.payload) });
|
||||||
break;
|
break;
|
||||||
case 'nostr.sign':
|
|
||||||
window.nostr?.signEvent(JSON.parse(data.payload))
|
|
||||||
.then((data) => websocket.send(JSON.stringify({ type: 'nostr.sign', data })))
|
|
||||||
.catch(() => console.warn('Failed to sign Nostr event.'));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -53,4 +53,3 @@ export { useHashtagStream } from './streaming/useHashtagStream';
|
||||||
export { useListStream } from './streaming/useListStream';
|
export { useListStream } from './streaming/useListStream';
|
||||||
export { useGroupStream } from './streaming/useGroupStream';
|
export { useGroupStream } from './streaming/useGroupStream';
|
||||||
export { useRemoteStream } from './streaming/useRemoteStream';
|
export { useRemoteStream } from './streaming/useRemoteStream';
|
||||||
export { useNostrStream } from './streaming/useNostrStream';
|
|
57
app/soapbox/api/hooks/nostr/useSignerStream.ts
Normal file
57
app/soapbox/api/hooks/nostr/useSignerStream.ts
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
import { relayInit, type Relay } from 'nostr-tools';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
import { useInstance } from 'soapbox/hooks';
|
||||||
|
import { connectRequestSchema } from 'soapbox/schemas/nostr';
|
||||||
|
import { jsonSchema } from 'soapbox/schemas/utils';
|
||||||
|
|
||||||
|
function useSignerStream() {
|
||||||
|
const { nostr } = useInstance();
|
||||||
|
|
||||||
|
const relayUrl = nostr.get('relay') as string | undefined;
|
||||||
|
const pubkey = nostr.get('pubkey') as string | undefined;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let relay: Relay | undefined;
|
||||||
|
|
||||||
|
if (relayUrl && pubkey && window.nostr?.nip04) {
|
||||||
|
relay = relayInit(relayUrl);
|
||||||
|
relay.connect();
|
||||||
|
|
||||||
|
relay
|
||||||
|
.sub([{ kinds: [24133], authors: [pubkey], limit: 0 }])
|
||||||
|
.on('event', async (event) => {
|
||||||
|
if (!relay || !window.nostr?.nip04) return;
|
||||||
|
|
||||||
|
const decrypted = await window.nostr.nip04.decrypt(pubkey, event.content);
|
||||||
|
const reqMsg = jsonSchema.pipe(connectRequestSchema).safeParse(decrypted);
|
||||||
|
|
||||||
|
if (!reqMsg.success) {
|
||||||
|
console.warn(decrypted);
|
||||||
|
console.warn(reqMsg.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const signed = await window.nostr.signEvent(reqMsg.data.params[0]);
|
||||||
|
const respMsg = {
|
||||||
|
id: reqMsg.data.id,
|
||||||
|
result: signed,
|
||||||
|
};
|
||||||
|
|
||||||
|
const respEvent = await window.nostr.signEvent({
|
||||||
|
kind: 24133,
|
||||||
|
content: await window.nostr.nip04.encrypt(pubkey, JSON.stringify(respMsg)),
|
||||||
|
tags: [['p', pubkey]],
|
||||||
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
|
});
|
||||||
|
|
||||||
|
relay.publish(respEvent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
relay?.close();
|
||||||
|
};
|
||||||
|
}, [relayUrl, pubkey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { useSignerStream };
|
|
@ -1,20 +0,0 @@
|
||||||
import { useFeatures, useLoggedIn } from 'soapbox/hooks';
|
|
||||||
|
|
||||||
import { useTimelineStream } from './useTimelineStream';
|
|
||||||
|
|
||||||
function useNostrStream() {
|
|
||||||
const features = useFeatures();
|
|
||||||
const { isLoggedIn } = useLoggedIn();
|
|
||||||
|
|
||||||
return useTimelineStream(
|
|
||||||
'nostr',
|
|
||||||
'nostr',
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
{
|
|
||||||
enabled: isLoggedIn && features.nostrSign && Boolean(window.nostr),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { useNostrStream };
|
|
|
@ -66,6 +66,7 @@ export const baseClient = (accessToken?: string | null, baseURL: string = ''): A
|
||||||
baseURL: isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : baseURL,
|
baseURL: isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : baseURL,
|
||||||
headers: Object.assign(accessToken ? {
|
headers: Object.assign(accessToken ? {
|
||||||
'Authorization': `Bearer ${accessToken}`,
|
'Authorization': `Bearer ${accessToken}`,
|
||||||
|
'X-Nostr-Sign': 'true',
|
||||||
} : {}),
|
} : {}),
|
||||||
transformResponse: [maybeParseJSON],
|
transformResponse: [maybeParseJSON],
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,7 +16,8 @@ import { register as registerPushNotifications } from 'soapbox/actions/push-noti
|
||||||
import { fetchScheduledStatuses } from 'soapbox/actions/scheduled-statuses';
|
import { fetchScheduledStatuses } from 'soapbox/actions/scheduled-statuses';
|
||||||
import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions';
|
import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions';
|
||||||
import { expandHomeTimeline } from 'soapbox/actions/timelines';
|
import { expandHomeTimeline } from 'soapbox/actions/timelines';
|
||||||
import { useNostrStream, useUserStream } from 'soapbox/api/hooks';
|
import { useUserStream } from 'soapbox/api/hooks';
|
||||||
|
import { useSignerStream } from 'soapbox/api/hooks/nostr/useSignerStream';
|
||||||
import GroupLookupHoc from 'soapbox/components/hoc/group-lookup-hoc';
|
import GroupLookupHoc from 'soapbox/components/hoc/group-lookup-hoc';
|
||||||
import withHoc from 'soapbox/components/hoc/with-hoc';
|
import withHoc from 'soapbox/components/hoc/with-hoc';
|
||||||
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
|
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
|
||||||
|
@ -443,7 +444,7 @@ const UI: React.FC<IUI> = ({ children }) => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useUserStream();
|
useUserStream();
|
||||||
useNostrStream();
|
useSignerStream();
|
||||||
|
|
||||||
// The user has logged in
|
// The user has logged in
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -62,6 +62,10 @@ describe('normalizeInstance()', () => {
|
||||||
uri: '',
|
uri: '',
|
||||||
urls: {},
|
urls: {},
|
||||||
version: '0.0.0',
|
version: '0.0.0',
|
||||||
|
nostr: {
|
||||||
|
pubkey: undefined,
|
||||||
|
relay: undefined,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = normalizeInstance(ImmutableMap());
|
const result = normalizeInstance(ImmutableMap());
|
||||||
|
|
|
@ -69,6 +69,10 @@ export const InstanceRecord = ImmutableRecord({
|
||||||
status_count: 0,
|
status_count: 0,
|
||||||
user_count: 0,
|
user_count: 0,
|
||||||
}),
|
}),
|
||||||
|
nostr: ImmutableMap<string, any>({
|
||||||
|
relay: undefined as string | undefined,
|
||||||
|
pubkey: undefined as string | undefined,
|
||||||
|
}),
|
||||||
title: '',
|
title: '',
|
||||||
thumbnail: '',
|
thumbnail: '',
|
||||||
uri: '',
|
uri: '',
|
||||||
|
|
34
app/soapbox/schemas/nostr.ts
Normal file
34
app/soapbox/schemas/nostr.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import { verifySignature } 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().positive();
|
||||||
|
|
||||||
|
/** 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(verifySignature);
|
||||||
|
|
||||||
|
/** NIP-46 signer request. */
|
||||||
|
const connectRequestSchema = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
method: z.literal('sign_event'),
|
||||||
|
params: z.tuple([eventTemplateSchema]),
|
||||||
|
});
|
||||||
|
|
||||||
|
export { nostrIdSchema, kindSchema, eventSchema, signedEventSchema, connectRequestSchema };
|
|
@ -30,4 +30,13 @@ function makeCustomEmojiMap(customEmojis: CustomEmoji[]) {
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
export { filteredArray, makeCustomEmojiMap, emojiSchema, contentSchema, dateSchema };
|
const jsonSchema = z.string().transform((value, ctx) => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(value) as unknown;
|
||||||
|
} catch (_e) {
|
||||||
|
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Invalid JSON' });
|
||||||
|
return z.NEVER;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export { filteredArray, makeCustomEmojiMap, emojiSchema, contentSchema, dateSchema, jsonSchema };
|
|
@ -3,6 +3,10 @@ import type { Event, EventTemplate } from 'nostr-tools';
|
||||||
interface Nostr {
|
interface Nostr {
|
||||||
getPublicKey(): Promise<string>
|
getPublicKey(): Promise<string>
|
||||||
signEvent(event: EventTemplate): Promise<Event>
|
signEvent(event: EventTemplate): Promise<Event>
|
||||||
|
nip04?: {
|
||||||
|
encrypt: (pubkey: string, plaintext: string) => Promise<string>
|
||||||
|
decrypt: (pubkey: string, ciphertext: string) => Promise<string>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Nostr;
|
export default Nostr;
|
|
@ -131,7 +131,7 @@
|
||||||
"localforage": "^1.10.0",
|
"localforage": "^1.10.0",
|
||||||
"lodash": "^4.7.11",
|
"lodash": "^4.7.11",
|
||||||
"mini-css-extract-plugin": "^2.6.0",
|
"mini-css-extract-plugin": "^2.6.0",
|
||||||
"nostr-tools": "^1.8.1",
|
"nostr-tools": "^1.14.2",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"postcss": "^8.4.14",
|
"postcss": "^8.4.14",
|
||||||
"postcss-loader": "^7.0.0",
|
"postcss-loader": "^7.0.0",
|
||||||
|
|
80
yarn.lock
80
yarn.lock
|
@ -2184,27 +2184,32 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
eslint-scope "5.1.1"
|
eslint-scope "5.1.1"
|
||||||
|
|
||||||
"@noble/curves@~0.8.3":
|
"@noble/ciphers@^0.2.0":
|
||||||
version "0.8.3"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-0.8.3.tgz#ad6d48baf2599cf1d58dcb734c14d5225c8996e0"
|
resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.2.0.tgz#a12cda60f3cf1ab5d7c77068c3711d2366649ed7"
|
||||||
integrity sha512-OqaOf4RWDaCRuBKJLDURrgVxjLmneGsiCXGuzYB5y95YithZMA6w4uk34DHSm0rKMrrYiaeZj48/81EvaAScLQ==
|
integrity sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==
|
||||||
|
|
||||||
|
"@noble/curves@1.1.0", "@noble/curves@~1.1.0":
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d"
|
||||||
|
integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/hashes" "1.3.0"
|
"@noble/hashes" "1.3.1"
|
||||||
|
|
||||||
"@noble/hashes@1.0.0":
|
"@noble/hashes@1.3.1":
|
||||||
version "1.0.0"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae"
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9"
|
||||||
integrity sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==
|
integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==
|
||||||
|
|
||||||
"@noble/hashes@1.3.0", "@noble/hashes@~1.3.0":
|
"@noble/hashes@~1.3.0":
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1"
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1"
|
||||||
integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==
|
integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==
|
||||||
|
|
||||||
"@noble/secp256k1@^1.7.1":
|
"@noble/hashes@~1.3.1":
|
||||||
version "1.7.1"
|
version "1.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c"
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
|
||||||
integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==
|
integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
|
||||||
|
|
||||||
"@nodelib/fs.scandir@2.1.5":
|
"@nodelib/fs.scandir@2.1.5":
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
|
@ -2471,24 +2476,24 @@
|
||||||
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.2.1.tgz#812edd4104a15a493dda1ccac0b352270d7a188c"
|
resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.2.1.tgz#812edd4104a15a493dda1ccac0b352270d7a188c"
|
||||||
integrity sha512-XiY0IsyHR+DXYS5vBxpoBe/8veTeoRpMHP+vDosLZxL5bnpetzI0igkxkLZS235ldLzyfkxF+2divEwWHP3vMQ==
|
integrity sha512-XiY0IsyHR+DXYS5vBxpoBe/8veTeoRpMHP+vDosLZxL5bnpetzI0igkxkLZS235ldLzyfkxF+2divEwWHP3vMQ==
|
||||||
|
|
||||||
"@scure/base@^1.1.1", "@scure/base@~1.1.0":
|
"@scure/base@1.1.1", "@scure/base@~1.1.0":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
||||||
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
||||||
|
|
||||||
"@scure/bip32@^1.1.5":
|
"@scure/bip32@1.3.1":
|
||||||
version "1.2.0"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.2.0.tgz#35692d8f8cc3207200239fc119f9e038e5f465df"
|
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10"
|
||||||
integrity sha512-O+vT/hBVk+ag2i6j2CDemwd1E1MtGt+7O1KzrPNsaNvSsiEK55MyPIxJIMI2PS8Ijj464B2VbQlpRoQXxw1uHg==
|
integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/curves" "~0.8.3"
|
"@noble/curves" "~1.1.0"
|
||||||
"@noble/hashes" "~1.3.0"
|
"@noble/hashes" "~1.3.1"
|
||||||
"@scure/base" "~1.1.0"
|
"@scure/base" "~1.1.0"
|
||||||
|
|
||||||
"@scure/bip39@^1.1.1":
|
"@scure/bip39@1.2.1":
|
||||||
version "1.2.0"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b"
|
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a"
|
||||||
integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg==
|
integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/hashes" "~1.3.0"
|
"@noble/hashes" "~1.3.0"
|
||||||
"@scure/base" "~1.1.0"
|
"@scure/base" "~1.1.0"
|
||||||
|
@ -8730,17 +8735,17 @@ normalize-url@^6.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
||||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
||||||
|
|
||||||
nostr-tools@^1.8.1:
|
nostr-tools@^1.14.2:
|
||||||
version "1.8.1"
|
version "1.14.2"
|
||||||
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.8.1.tgz#4e54a354cc88ea0200634da3ee5a1c3466e1794c"
|
resolved "https://registry.yarnpkg.com/nostr-tools/-/nostr-tools-1.14.2.tgz#161c9401467725e87c07fcf1c9924d31b12fd45c"
|
||||||
integrity sha512-/2IUe5xINUYT5hYBoEz51dfRaodbRHnyF8n+ZbKWCoh0ZRX6AL88OoDNrWaWWo7tP5j5OyzSL9g/z4TP7bshEA==
|
integrity sha512-QEe8+tMDW0632eNDcQ+EG1edmsCXLV4WPiWLDcdT3uoE+GM15pVcy18sKwbN7SmgO4GKFEqQ49k45eANC6++SQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/hashes" "1.0.0"
|
"@noble/ciphers" "^0.2.0"
|
||||||
"@noble/secp256k1" "^1.7.1"
|
"@noble/curves" "1.1.0"
|
||||||
"@scure/base" "^1.1.1"
|
"@noble/hashes" "1.3.1"
|
||||||
"@scure/bip32" "^1.1.5"
|
"@scure/base" "1.1.1"
|
||||||
"@scure/bip39" "^1.1.1"
|
"@scure/bip32" "1.3.1"
|
||||||
prettier "^2.8.4"
|
"@scure/bip39" "1.2.1"
|
||||||
|
|
||||||
npm-run-path@^4.0.1:
|
npm-run-path@^4.0.1:
|
||||||
version "4.0.1"
|
version "4.0.1"
|
||||||
|
@ -9512,11 +9517,6 @@ prelude-ls@~1.1.2:
|
||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||||
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
|
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
|
||||||
|
|
||||||
prettier@^2.8.4:
|
|
||||||
version "2.8.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450"
|
|
||||||
integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==
|
|
||||||
|
|
||||||
pretty-error@^4.0.0:
|
pretty-error@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6"
|
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6"
|
||||||
|
|
Loading…
Reference in a new issue