2023-10-04 22:19:19 +00:00
|
|
|
import { NiceRelay } from 'nostr-machina';
|
2024-02-11 18:45:33 +00:00
|
|
|
import { type NostrEvent } from 'nspec';
|
2023-10-04 22:19:19 +00:00
|
|
|
import { useEffect, useMemo } from 'react';
|
2023-08-27 04:24:18 +00:00
|
|
|
|
2024-02-11 18:40:14 +00:00
|
|
|
import { signer } from 'soapbox/features/nostr/sign';
|
2023-08-27 04:24:18 +00:00
|
|
|
import { useInstance } from 'soapbox/hooks';
|
2024-01-17 00:35:00 +00:00
|
|
|
import { connectRequestSchema, nwcRequestSchema } from 'soapbox/schemas/nostr';
|
2023-08-27 04:24:18 +00:00
|
|
|
import { jsonSchema } from 'soapbox/schemas/utils';
|
|
|
|
|
|
|
|
function useSignerStream() {
|
2023-09-24 01:41:24 +00:00
|
|
|
const instance = useInstance();
|
2023-08-27 04:24:18 +00:00
|
|
|
|
2023-09-24 01:41:24 +00:00
|
|
|
const relayUrl = instance.nostr?.relay;
|
|
|
|
const pubkey = instance.nostr?.pubkey;
|
2023-08-27 04:24:18 +00:00
|
|
|
|
2023-10-04 22:19:19 +00:00
|
|
|
const relay = useMemo(() => {
|
2024-02-11 18:45:33 +00:00
|
|
|
if (relayUrl && signer) {
|
2023-10-04 22:19:19 +00:00
|
|
|
return new NiceRelay(relayUrl);
|
|
|
|
}
|
2024-02-11 18:45:33 +00:00
|
|
|
}, [relayUrl, !!signer]);
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-02-11 18:45:33 +00:00
|
|
|
async function handleConnectEvent(event: NostrEvent) {
|
|
|
|
if (!relay || !pubkey || !signer) return;
|
2024-02-11 18:40:14 +00:00
|
|
|
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-01-17 00:35:00 +00:00
|
|
|
const reqMsg = jsonSchema.pipe(connectRequestSchema).safeParse(decrypted);
|
|
|
|
if (!reqMsg.success) {
|
|
|
|
console.warn(decrypted);
|
|
|
|
console.warn(reqMsg.error);
|
|
|
|
return;
|
|
|
|
}
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-01-17 00:35:00 +00:00
|
|
|
const respMsg = {
|
|
|
|
id: reqMsg.data.id,
|
2024-02-11 18:40:14 +00:00
|
|
|
result: await signer.signEvent(reqMsg.data.params[0]),
|
2024-01-17 00:35:00 +00:00
|
|
|
};
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-02-11 18:40:14 +00:00
|
|
|
const respEvent = await signer.signEvent({
|
2024-01-17 00:35:00 +00:00
|
|
|
kind: 24133,
|
2024-02-11 18:40:14 +00:00
|
|
|
content: await signer.nip04!.encrypt(pubkey, JSON.stringify(respMsg)),
|
2024-01-17 00:35:00 +00:00
|
|
|
tags: [['p', pubkey]],
|
|
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
|
|
});
|
|
|
|
|
|
|
|
relay.send(['EVENT', respEvent]);
|
|
|
|
}
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-02-11 18:45:33 +00:00
|
|
|
async function handleWalletEvent(event: NostrEvent) {
|
|
|
|
if (!relay || !pubkey || !signer) return;
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-02-11 18:40:14 +00:00
|
|
|
const decrypted = await signer.nip04!.decrypt(pubkey, event.content);
|
2023-10-04 22:19:19 +00:00
|
|
|
|
2024-01-17 00:35:00 +00:00
|
|
|
const reqMsg = jsonSchema.pipe(nwcRequestSchema).safeParse(decrypted);
|
|
|
|
if (!reqMsg.success) {
|
|
|
|
console.warn(decrypted);
|
|
|
|
console.warn(reqMsg.error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
await window.webln?.enable();
|
|
|
|
await window.webln?.sendPayment(reqMsg.data.params.invoice);
|
|
|
|
}
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (!relay || !pubkey) return;
|
|
|
|
const sub = relay.req([{ kinds: [24133, 23194], authors: [pubkey], limit: 0 }]);
|
|
|
|
|
|
|
|
const readEvents = async () => {
|
|
|
|
for await (const event of sub) {
|
|
|
|
switch (event.kind) {
|
|
|
|
case 24133:
|
|
|
|
await handleConnectEvent(event);
|
|
|
|
break;
|
|
|
|
case 23194:
|
|
|
|
await handleWalletEvent(event);
|
|
|
|
break;
|
|
|
|
}
|
2023-10-04 22:19:19 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
readEvents();
|
|
|
|
|
2023-08-27 04:24:18 +00:00
|
|
|
return () => {
|
|
|
|
relay?.close();
|
|
|
|
};
|
2023-10-04 22:19:19 +00:00
|
|
|
}, [relay, pubkey]);
|
2023-08-27 04:24:18 +00:00
|
|
|
}
|
|
|
|
|
2023-08-28 17:58:11 +00:00
|
|
|
export { useSignerStream };
|