mirror of
https://github.com/aljazceru/ditto.git
synced 2026-01-29 18:14:23 +01:00
Merge branch 'main' into postgres-support-testing
Update local branch to latest. This branch has the NIP-05 but it will be overriden
This commit is contained in:
@@ -14,6 +14,7 @@ import { RelayError } from '@/RelayError.ts';
|
||||
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
||||
import { Storages } from '@/storages.ts';
|
||||
import { nostrNow } from '@/utils.ts';
|
||||
import { purifyEvent } from '@/storages/hydrate.ts';
|
||||
|
||||
const debug = Debug('ditto:api');
|
||||
|
||||
@@ -152,7 +153,7 @@ async function publishEvent(event: NostrEvent, c: AppContext): Promise<NostrEven
|
||||
try {
|
||||
await pipeline.handleEvent(event, c.req.raw.signal);
|
||||
const client = await Storages.client();
|
||||
await client.event(event);
|
||||
await client.event(purifyEvent(event));
|
||||
} catch (e) {
|
||||
if (e instanceof RelayError) {
|
||||
throw new HTTPException(422, {
|
||||
|
||||
29
src/utils/outbox.test.ts
Normal file
29
src/utils/outbox.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { MockRelay } from '@nostrify/nostrify/test';
|
||||
import { eventFixture } from '@/test.ts';
|
||||
import { getRelays } from '@/utils/outbox.ts';
|
||||
import { assertEquals } from '@std/assert';
|
||||
|
||||
Deno.test('Get write relays - kind 10002', async () => {
|
||||
const db = new MockRelay();
|
||||
|
||||
const relayListMetadata = await eventFixture('kind-10002-alex');
|
||||
|
||||
await db.event(relayListMetadata);
|
||||
|
||||
const relays = await getRelays(db, relayListMetadata.pubkey);
|
||||
|
||||
assertEquals(relays.size, 6);
|
||||
});
|
||||
|
||||
Deno.test('Get write relays with invalid URL - kind 10002', async () => {
|
||||
const db = new MockRelay();
|
||||
|
||||
const relayListMetadata = await eventFixture('kind-10002-alex');
|
||||
relayListMetadata.tags[0] = ['r', 'yolo'];
|
||||
|
||||
await db.event(relayListMetadata);
|
||||
|
||||
const relays = await getRelays(db, relayListMetadata.pubkey);
|
||||
|
||||
assertEquals(relays.size, 5);
|
||||
});
|
||||
@@ -2,11 +2,11 @@ import { NStore } from '@nostrify/nostrify';
|
||||
|
||||
import { Conf } from '@/config.ts';
|
||||
|
||||
export async function getRelays(store: NStore, _pubkey: string): Promise<Set<string>> {
|
||||
export async function getRelays(store: NStore, pubkey: string): Promise<Set<string>> {
|
||||
const relays = new Set<`wss://${string}`>();
|
||||
|
||||
const events = await store.query([
|
||||
{ kinds: [10002], authors: [/*pubkey, */ Conf.pubkey], limit: 2 },
|
||||
{ kinds: [10002], authors: [pubkey, Conf.pubkey], limit: 2 },
|
||||
]);
|
||||
|
||||
for (const event of events) {
|
||||
|
||||
60
src/utils/zap-split.test.ts
Normal file
60
src/utils/zap-split.test.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { assertEquals } from '@std/assert';
|
||||
import { generateSecretKey, getPublicKey } from 'nostr-tools';
|
||||
|
||||
import { genEvent } from '@/test.ts';
|
||||
import { getZapSplits } from '@/utils/zap-split.ts';
|
||||
import { getTestDB } from '@/test.ts';
|
||||
|
||||
Deno.test('Get zap splits in DittoZapSplits format', async () => {
|
||||
const { store } = await getTestDB();
|
||||
|
||||
const sk = generateSecretKey();
|
||||
const pubkey = getPublicKey(sk);
|
||||
|
||||
const event = genEvent({
|
||||
kind: 30078,
|
||||
tags: [
|
||||
['d', 'pub.ditto.zapSplits'],
|
||||
['p', '47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4', '2', 'Patrick developer'],
|
||||
['p', '0461fcbecc4c3374439932d6b8f11269ccdb7cc973ad7a50ae362db135a474dd', '3', 'Alex creator of Ditto'],
|
||||
],
|
||||
}, sk);
|
||||
await store.event(event);
|
||||
|
||||
const eventFromDb = await store.query([{ kinds: [30078], authors: [pubkey] }]);
|
||||
|
||||
assertEquals(eventFromDb.length, 1);
|
||||
|
||||
const zapSplits = await getZapSplits(store, pubkey);
|
||||
|
||||
assertEquals(zapSplits, {
|
||||
'0461fcbecc4c3374439932d6b8f11269ccdb7cc973ad7a50ae362db135a474dd': { amount: 3, message: 'Alex creator of Ditto' },
|
||||
'47259076c85f9240e852420d7213c95e95102f1de929fb60f33a2c32570c98c4': { amount: 2, message: 'Patrick developer' },
|
||||
});
|
||||
|
||||
assertEquals(await getZapSplits(store, 'garbage'), undefined);
|
||||
});
|
||||
|
||||
Deno.test('Zap split is empty', async () => {
|
||||
const { store } = await getTestDB();
|
||||
|
||||
const sk = generateSecretKey();
|
||||
const pubkey = getPublicKey(sk);
|
||||
|
||||
const event = genEvent({
|
||||
kind: 30078,
|
||||
tags: [
|
||||
['d', 'pub.ditto.zapSplits'],
|
||||
['p', 'baka'],
|
||||
],
|
||||
}, sk);
|
||||
await store.event(event);
|
||||
|
||||
const eventFromDb = await store.query([{ kinds: [30078], authors: [pubkey] }]);
|
||||
|
||||
assertEquals(eventFromDb.length, 1);
|
||||
|
||||
const zapSplits = await getZapSplits(store, pubkey);
|
||||
|
||||
assertEquals(zapSplits, {});
|
||||
});
|
||||
62
src/utils/zap-split.ts
Normal file
62
src/utils/zap-split.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
||||
import { Conf } from '@/config.ts';
|
||||
import { handleEvent } from '@/pipeline.ts';
|
||||
import { NSchema as n, NStore } from '@nostrify/nostrify';
|
||||
import { nostrNow } from '@/utils.ts';
|
||||
import { percentageSchema } from '@/schema.ts';
|
||||
import { Storages } from '@/storages.ts';
|
||||
|
||||
type Pubkey = string;
|
||||
type ExtraMessage = string;
|
||||
/** Number from 1 to 100, stringified. */
|
||||
type splitPercentages = number;
|
||||
|
||||
export type DittoZapSplits = {
|
||||
[key: Pubkey]: { amount: splitPercentages; message: ExtraMessage };
|
||||
};
|
||||
|
||||
/** Gets zap splits from NIP-78 in DittoZapSplits format. */
|
||||
export async function getZapSplits(store: NStore, pubkey: string): Promise<DittoZapSplits | undefined> {
|
||||
const zapSplits: DittoZapSplits = {};
|
||||
|
||||
const [event] = await store.query([{
|
||||
authors: [pubkey],
|
||||
kinds: [30078],
|
||||
'#d': ['pub.ditto.zapSplits'],
|
||||
limit: 1,
|
||||
}]);
|
||||
if (!event) return;
|
||||
|
||||
for (const tag of event.tags) {
|
||||
if (
|
||||
tag[0] === 'p' && n.id().safeParse(tag[1]).success &&
|
||||
percentageSchema.safeParse(tag[2]).success
|
||||
) {
|
||||
zapSplits[tag[1]] = { amount: Number(tag[2]), message: tag[3] };
|
||||
}
|
||||
}
|
||||
|
||||
return zapSplits;
|
||||
}
|
||||
|
||||
export async function seedZapSplits() {
|
||||
const store = await Storages.admin();
|
||||
|
||||
const zap_split: DittoZapSplits | undefined = await getZapSplits(store, Conf.pubkey);
|
||||
if (!zap_split) {
|
||||
const dittoPubkey = '781a1527055f74c1f70230f10384609b34548f8ab6a0a6caa74025827f9fdae5';
|
||||
const dittoMsg = 'Official Ditto Account';
|
||||
|
||||
const signer = new AdminSigner();
|
||||
const event = await signer.signEvent({
|
||||
content: '',
|
||||
created_at: nostrNow(),
|
||||
kind: 30078,
|
||||
tags: [
|
||||
['d', 'pub.ditto.zapSplits'],
|
||||
['p', dittoPubkey, '5', dittoMsg],
|
||||
],
|
||||
});
|
||||
await handleEvent(event, AbortSignal.timeout(5000));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user