mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
Make auth middleware work again (in a hacky way for now)
This commit is contained in:
parent
67aec57990
commit
e1bf86eb21
5 changed files with 54 additions and 55 deletions
|
|
@ -7,6 +7,7 @@ import { type Context, Handler, Input as HonoInput, MiddlewareHandler } from '@h
|
||||||
import { every } from '@hono/hono/combine';
|
import { every } from '@hono/hono/combine';
|
||||||
import { cors } from '@hono/hono/cors';
|
import { cors } from '@hono/hono/cors';
|
||||||
import { serveStatic } from '@hono/hono/deno';
|
import { serveStatic } from '@hono/hono/deno';
|
||||||
|
import { createFactory } from '@hono/hono/factory';
|
||||||
import { NostrEvent, NostrSigner, NRelay, NUploader } from '@nostrify/nostrify';
|
import { NostrEvent, NostrSigner, NRelay, NUploader } from '@nostrify/nostrify';
|
||||||
|
|
||||||
import '@/startup.ts';
|
import '@/startup.ts';
|
||||||
|
|
@ -137,7 +138,7 @@ import { metricsController } from '@/controllers/metrics.ts';
|
||||||
import { manifestController } from '@/controllers/manifest.ts';
|
import { manifestController } from '@/controllers/manifest.ts';
|
||||||
import { nodeInfoController, nodeInfoSchemaController } from '@/controllers/well-known/nodeinfo.ts';
|
import { nodeInfoController, nodeInfoSchemaController } from '@/controllers/well-known/nodeinfo.ts';
|
||||||
import { nostrController } from '@/controllers/well-known/nostr.ts';
|
import { nostrController } from '@/controllers/well-known/nostr.ts';
|
||||||
import { auth98Middleware, requireProof, requireRole } from '@/middleware/auth98Middleware.ts';
|
import { auth98Middleware, requireProof as _requireProof, requireRole } from '@/middleware/auth98Middleware.ts';
|
||||||
import { cacheControlMiddleware } from '@/middleware/cacheControlMiddleware.ts';
|
import { cacheControlMiddleware } from '@/middleware/cacheControlMiddleware.ts';
|
||||||
import { cspMiddleware } from '@/middleware/cspMiddleware.ts';
|
import { cspMiddleware } from '@/middleware/cspMiddleware.ts';
|
||||||
import { metricsMiddleware } from '@/middleware/metricsMiddleware.ts';
|
import { metricsMiddleware } from '@/middleware/metricsMiddleware.ts';
|
||||||
|
|
@ -197,7 +198,10 @@ const ratelimit = every(
|
||||||
rateLimitMiddleware(300, Time.minutes(5), false),
|
rateLimitMiddleware(300, Time.minutes(5), false),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const factory = createFactory();
|
||||||
const requireSigner = userMiddleware({ privileged: false, required: true });
|
const requireSigner = userMiddleware({ privileged: false, required: true });
|
||||||
|
const requireAdmin = factory.createHandlers(requireSigner, requireRole('admin'));
|
||||||
|
const requireProof = factory.createHandlers(requireSigner, _requireProof());
|
||||||
|
|
||||||
app.use('/api/*', metricsMiddleware, ratelimit, paginationMiddleware(), logiMiddleware);
|
app.use('/api/*', metricsMiddleware, ratelimit, paginationMiddleware(), logiMiddleware);
|
||||||
app.use('/.well-known/*', metricsMiddleware, ratelimit, logiMiddleware);
|
app.use('/.well-known/*', metricsMiddleware, ratelimit, logiMiddleware);
|
||||||
|
|
@ -258,7 +262,7 @@ app.post('/oauth/revoke', revokeTokenController);
|
||||||
app.post('/oauth/authorize', oauthAuthorizeController);
|
app.post('/oauth/authorize', oauthAuthorizeController);
|
||||||
app.get('/oauth/authorize', oauthController);
|
app.get('/oauth/authorize', oauthController);
|
||||||
|
|
||||||
app.post('/api/v1/accounts', requireProof(), createAccountController);
|
app.post('/api/v1/accounts', ...requireProof, createAccountController);
|
||||||
app.get('/api/v1/accounts/verify_credentials', requireSigner, verifyCredentialsController);
|
app.get('/api/v1/accounts/verify_credentials', requireSigner, verifyCredentialsController);
|
||||||
app.patch('/api/v1/accounts/update_credentials', requireSigner, updateCredentialsController);
|
app.patch('/api/v1/accounts/update_credentials', requireSigner, updateCredentialsController);
|
||||||
app.get('/api/v1/accounts/search', accountSearchController);
|
app.get('/api/v1/accounts/search', accountSearchController);
|
||||||
|
|
@ -372,25 +376,25 @@ app.get('/api/v1/bookmarks', requireSigner, bookmarksController);
|
||||||
app.get('/api/v1/blocks', requireSigner, blocksController);
|
app.get('/api/v1/blocks', requireSigner, blocksController);
|
||||||
app.get('/api/v1/mutes', requireSigner, mutesController);
|
app.get('/api/v1/mutes', requireSigner, mutesController);
|
||||||
|
|
||||||
app.get('/api/v1/markers', requireProof(), markersController);
|
app.get('/api/v1/markers', ...requireProof, markersController);
|
||||||
app.post('/api/v1/markers', requireProof(), updateMarkersController);
|
app.post('/api/v1/markers', ...requireProof, updateMarkersController);
|
||||||
|
|
||||||
app.get('/api/v1/push/subscription', requireSigner, getSubscriptionController);
|
app.get('/api/v1/push/subscription', requireSigner, getSubscriptionController);
|
||||||
app.post('/api/v1/push/subscription', requireProof(), pushSubscribeController);
|
app.post('/api/v1/push/subscription', ...requireProof, pushSubscribeController);
|
||||||
|
|
||||||
app.get('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions', reactionsController);
|
app.get('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions', reactionsController);
|
||||||
app.get('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', reactionsController);
|
app.get('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', reactionsController);
|
||||||
app.put('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', requireSigner, reactionController);
|
app.put('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', requireSigner, reactionController);
|
||||||
app.delete('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', requireSigner, deleteReactionController);
|
app.delete('/api/v1/pleroma/statuses/:id{[0-9a-f]{64}}/reactions/:emoji', requireSigner, deleteReactionController);
|
||||||
|
|
||||||
app.get('/api/v1/pleroma/admin/config', requireRole('admin'), configController);
|
app.get('/api/v1/pleroma/admin/config', ...requireAdmin, configController);
|
||||||
app.post('/api/v1/pleroma/admin/config', requireRole('admin'), updateConfigController);
|
app.post('/api/v1/pleroma/admin/config', ...requireAdmin, updateConfigController);
|
||||||
app.delete('/api/v1/pleroma/admin/statuses/:id', requireRole('admin'), pleromaAdminDeleteStatusController);
|
app.delete('/api/v1/pleroma/admin/statuses/:id', ...requireAdmin, pleromaAdminDeleteStatusController);
|
||||||
|
|
||||||
app.get('/api/v1/admin/ditto/relays', requireRole('admin'), adminRelaysController);
|
app.get('/api/v1/admin/ditto/relays', ...requireAdmin, adminRelaysController);
|
||||||
app.put('/api/v1/admin/ditto/relays', requireRole('admin'), adminSetRelaysController);
|
app.put('/api/v1/admin/ditto/relays', ...requireAdmin, adminSetRelaysController);
|
||||||
|
|
||||||
app.put('/api/v1/admin/ditto/instance', requireRole('admin'), updateInstanceController);
|
app.put('/api/v1/admin/ditto/instance', ...requireAdmin, updateInstanceController);
|
||||||
|
|
||||||
app.post('/api/v1/ditto/names', requireSigner, nameRequestController);
|
app.post('/api/v1/ditto/names', requireSigner, nameRequestController);
|
||||||
app.get('/api/v1/ditto/names', requireSigner, nameRequestsController);
|
app.get('/api/v1/ditto/names', requireSigner, nameRequestsController);
|
||||||
|
|
@ -399,7 +403,7 @@ app.get('/api/v1/ditto/captcha', rateLimitMiddleware(3, Time.minutes(1)), captch
|
||||||
app.post(
|
app.post(
|
||||||
'/api/v1/ditto/captcha/:id/verify',
|
'/api/v1/ditto/captcha/:id/verify',
|
||||||
rateLimitMiddleware(8, Time.minutes(1)),
|
rateLimitMiddleware(8, Time.minutes(1)),
|
||||||
requireProof(),
|
...requireProof,
|
||||||
captchaVerifyController,
|
captchaVerifyController,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -410,8 +414,8 @@ app.get(
|
||||||
);
|
);
|
||||||
app.get('/api/v1/ditto/:id{[0-9a-f]{64}}/zap_splits', statusZapSplitsController);
|
app.get('/api/v1/ditto/:id{[0-9a-f]{64}}/zap_splits', statusZapSplitsController);
|
||||||
|
|
||||||
app.put('/api/v1/admin/ditto/zap_splits', requireRole('admin'), updateZapSplitsController);
|
app.put('/api/v1/admin/ditto/zap_splits', ...requireAdmin, updateZapSplitsController);
|
||||||
app.delete('/api/v1/admin/ditto/zap_splits', requireRole('admin'), deleteZapSplitsController);
|
app.delete('/api/v1/admin/ditto/zap_splits', ...requireAdmin, deleteZapSplitsController);
|
||||||
|
|
||||||
app.post('/api/v1/ditto/zap', requireSigner, zapController);
|
app.post('/api/v1/ditto/zap', requireSigner, zapController);
|
||||||
app.get('/api/v1/ditto/statuses/:id{[0-9a-f]{64}}/zapped_by', zappedByController);
|
app.get('/api/v1/ditto/statuses/:id{[0-9a-f]{64}}/zapped_by', zappedByController);
|
||||||
|
|
@ -419,35 +423,35 @@ app.get('/api/v1/ditto/statuses/:id{[0-9a-f]{64}}/zapped_by', zappedByController
|
||||||
app.route('/api/v1/ditto/cashu', cashuApp);
|
app.route('/api/v1/ditto/cashu', cashuApp);
|
||||||
|
|
||||||
app.post('/api/v1/reports', requireSigner, reportController);
|
app.post('/api/v1/reports', requireSigner, reportController);
|
||||||
app.get('/api/v1/admin/reports', requireSigner, requireRole('admin'), adminReportsController);
|
app.get('/api/v1/admin/reports', requireSigner, ...requireAdmin, adminReportsController);
|
||||||
app.get('/api/v1/admin/reports/:id{[0-9a-f]{64}}', requireSigner, requireRole('admin'), adminReportController);
|
app.get('/api/v1/admin/reports/:id{[0-9a-f]{64}}', requireSigner, ...requireAdmin, adminReportController);
|
||||||
app.post(
|
app.post(
|
||||||
'/api/v1/admin/reports/:id{[0-9a-f]{64}}/resolve',
|
'/api/v1/admin/reports/:id{[0-9a-f]{64}}/resolve',
|
||||||
requireSigner,
|
requireSigner,
|
||||||
requireRole('admin'),
|
...requireAdmin,
|
||||||
adminReportResolveController,
|
adminReportResolveController,
|
||||||
);
|
);
|
||||||
app.post(
|
app.post(
|
||||||
'/api/v1/admin/reports/:id{[0-9a-f]{64}}/reopen',
|
'/api/v1/admin/reports/:id{[0-9a-f]{64}}/reopen',
|
||||||
requireSigner,
|
requireSigner,
|
||||||
requireRole('admin'),
|
...requireAdmin,
|
||||||
adminReportReopenController,
|
adminReportReopenController,
|
||||||
);
|
);
|
||||||
|
|
||||||
app.get('/api/v1/admin/accounts', requireRole('admin'), adminAccountsController);
|
app.get('/api/v1/admin/accounts', ...requireAdmin, adminAccountsController);
|
||||||
app.post('/api/v1/admin/accounts/:id{[0-9a-f]{64}}/action', requireSigner, requireRole('admin'), adminActionController);
|
app.post('/api/v1/admin/accounts/:id{[0-9a-f]{64}}/action', requireSigner, ...requireAdmin, adminActionController);
|
||||||
app.post(
|
app.post(
|
||||||
'/api/v1/admin/accounts/:id{[0-9a-f]{64}}/approve',
|
'/api/v1/admin/accounts/:id{[0-9a-f]{64}}/approve',
|
||||||
requireSigner,
|
requireSigner,
|
||||||
requireRole('admin'),
|
...requireAdmin,
|
||||||
adminApproveController,
|
adminApproveController,
|
||||||
);
|
);
|
||||||
app.post('/api/v1/admin/accounts/:id{[0-9a-f]{64}}/reject', requireSigner, requireRole('admin'), adminRejectController);
|
app.post('/api/v1/admin/accounts/:id{[0-9a-f]{64}}/reject', requireSigner, ...requireAdmin, adminRejectController);
|
||||||
|
|
||||||
app.put('/api/v1/pleroma/admin/users/tag', requireRole('admin'), pleromaAdminTagController);
|
app.put('/api/v1/pleroma/admin/users/tag', ...requireAdmin, pleromaAdminTagController);
|
||||||
app.delete('/api/v1/pleroma/admin/users/tag', requireRole('admin'), pleromaAdminUntagController);
|
app.delete('/api/v1/pleroma/admin/users/tag', ...requireAdmin, pleromaAdminUntagController);
|
||||||
app.patch('/api/v1/pleroma/admin/users/suggest', requireRole('admin'), pleromaAdminSuggestController);
|
app.patch('/api/v1/pleroma/admin/users/suggest', ...requireAdmin, pleromaAdminSuggestController);
|
||||||
app.patch('/api/v1/pleroma/admin/users/unsuggest', requireRole('admin'), pleromaAdminUnsuggestController);
|
app.patch('/api/v1/pleroma/admin/users/unsuggest', ...requireAdmin, pleromaAdminUnsuggestController);
|
||||||
|
|
||||||
// Not (yet) implemented.
|
// Not (yet) implemented.
|
||||||
app.get('/api/v1/custom_emojis', emptyArrayController);
|
app.get('/api/v1/custom_emojis', emptyArrayController);
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ app.put('/wallet', userMiddleware({ privileged: false, required: true }), requir
|
||||||
await createEvent({
|
await createEvent({
|
||||||
kind: 17375,
|
kind: 17375,
|
||||||
content: encryptedWalletContentTags,
|
content: encryptedWalletContentTags,
|
||||||
|
// @ts-ignore kill me
|
||||||
}, c);
|
}, c);
|
||||||
|
|
||||||
// Nutzap information
|
// Nutzap information
|
||||||
|
|
@ -103,6 +104,7 @@ app.put('/wallet', userMiddleware({ privileged: false, required: true }), requir
|
||||||
['relay', conf.relay], // TODO: add more relays once things get more stable
|
['relay', conf.relay], // TODO: add more relays once things get more stable
|
||||||
['pubkey', p2pk],
|
['pubkey', p2pk],
|
||||||
],
|
],
|
||||||
|
// @ts-ignore kill me
|
||||||
}, c);
|
}, c);
|
||||||
|
|
||||||
// TODO: hydrate wallet and add a 'balance' field when a 'renderWallet' view function is created
|
// TODO: hydrate wallet and add a 'balance' field when a 'renderWallet' view function is created
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ import { NostrEvent } from '@nostrify/nostrify';
|
||||||
|
|
||||||
import { type AppContext, type AppMiddleware } from '@/app.ts';
|
import { type AppContext, type AppMiddleware } from '@/app.ts';
|
||||||
import { ReadOnlySigner } from '@/signers/ReadOnlySigner.ts';
|
import { ReadOnlySigner } from '@/signers/ReadOnlySigner.ts';
|
||||||
import { Storages } from '@/storages.ts';
|
|
||||||
import { localRequest } from '@/utils/api.ts';
|
import { localRequest } from '@/utils/api.ts';
|
||||||
import {
|
import {
|
||||||
buildAuthEventTemplate,
|
buildAuthEventTemplate,
|
||||||
|
|
@ -40,10 +39,9 @@ type UserRole = 'user' | 'admin';
|
||||||
/** Require the user to prove their role before invoking the controller. */
|
/** Require the user to prove their role before invoking the controller. */
|
||||||
function requireRole(role: UserRole, opts?: ParseAuthRequestOpts): AppMiddleware {
|
function requireRole(role: UserRole, opts?: ParseAuthRequestOpts): AppMiddleware {
|
||||||
return withProof(async (c, proof, next) => {
|
return withProof(async (c, proof, next) => {
|
||||||
const { conf } = c.var;
|
const { conf, relay } = c.var;
|
||||||
const store = await Storages.db();
|
|
||||||
|
|
||||||
const [user] = await store.query([{
|
const [user] = await relay.query([{
|
||||||
kinds: [30382],
|
kinds: [30382],
|
||||||
authors: [await conf.signer.getPublicKey()],
|
authors: [await conf.signer.getPublicKey()],
|
||||||
'#d': [proof.pubkey],
|
'#d': [proof.pubkey],
|
||||||
|
|
@ -108,6 +106,7 @@ function withProof(
|
||||||
/** Get the proof over Nostr Connect. */
|
/** Get the proof over Nostr Connect. */
|
||||||
async function obtainProof(c: AppContext, opts?: ParseAuthRequestOpts) {
|
async function obtainProof(c: AppContext, opts?: ParseAuthRequestOpts) {
|
||||||
const signer = c.var.user?.signer;
|
const signer = c.var.user?.signer;
|
||||||
|
|
||||||
if (!signer) {
|
if (!signer) {
|
||||||
throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
res: c.json({ error: 'No way to sign Nostr event' }, 401),
|
res: c.json({ error: 'No way to sign Nostr event' }, 401),
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
import { CashuMint, CashuWallet, getEncodedToken, type Proof } from '@cashu/cashu-ts';
|
import { CashuMint, CashuWallet, getEncodedToken, type Proof } from '@cashu/cashu-ts';
|
||||||
import { type DittoConf } from '@ditto/conf';
|
|
||||||
import { MiddlewareHandler } from '@hono/hono';
|
import { MiddlewareHandler } from '@hono/hono';
|
||||||
import { HTTPException } from '@hono/hono/http-exception';
|
import { HTTPException } from '@hono/hono/http-exception';
|
||||||
import { getPublicKey } from 'nostr-tools';
|
import { getPublicKey } from 'nostr-tools';
|
||||||
import { NostrFilter, NostrSigner, NSchema as n, NStore } from '@nostrify/nostrify';
|
import { NostrFilter, NSchema as n } from '@nostrify/nostrify';
|
||||||
import { SetRequired } from 'type-fest';
|
|
||||||
import { stringToBytes } from '@scure/base';
|
import { stringToBytes } from '@scure/base';
|
||||||
import { logi } from '@soapbox/logi';
|
import { logi } from '@soapbox/logi';
|
||||||
|
|
||||||
|
import { AppEnv } from '@/app.ts';
|
||||||
import { isNostrId } from '@/utils.ts';
|
import { isNostrId } from '@/utils.ts';
|
||||||
import { errorJson } from '@/utils/log.ts';
|
import { errorJson } from '@/utils/log.ts';
|
||||||
import { createEvent } from '@/utils/api.ts';
|
import { createEvent } from '@/utils/api.ts';
|
||||||
|
|
@ -17,33 +16,28 @@ import { z } from 'zod';
|
||||||
* Swap nutzaps into wallet (create new events) if the user has a wallet, otheriwse, just fallthrough.
|
* Swap nutzaps into wallet (create new events) if the user has a wallet, otheriwse, just fallthrough.
|
||||||
* Errors are only thrown if 'signer' and 'store' middlewares are not set.
|
* Errors are only thrown if 'signer' and 'store' middlewares are not set.
|
||||||
*/
|
*/
|
||||||
export const swapNutzapsMiddleware: MiddlewareHandler<
|
export const swapNutzapsMiddleware: MiddlewareHandler<AppEnv> = async (c, next) => {
|
||||||
{ Variables: { signer: SetRequired<NostrSigner, 'nip44'>; store: NStore; conf: DittoConf } }
|
const { conf, relay, user, signal } = c.var;
|
||||||
> = async (c, next) => {
|
|
||||||
const { conf } = c.var;
|
|
||||||
const signer = c.get('signer');
|
|
||||||
const store = c.get('store');
|
|
||||||
|
|
||||||
if (!signer) {
|
if (!user) {
|
||||||
throw new HTTPException(401, { message: 'No pubkey provided' });
|
throw new HTTPException(401, { message: 'No pubkey provided' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!signer.nip44) {
|
if (!user.signer.nip44) {
|
||||||
throw new HTTPException(401, { message: 'No NIP-44 signer provided' });
|
throw new HTTPException(401, { message: 'No NIP-44 signer provided' });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!store) {
|
if (!relay) {
|
||||||
throw new HTTPException(401, { message: 'No store provided' });
|
throw new HTTPException(401, { message: 'No store provided' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const { signal } = c.req.raw;
|
const pubkey = await user.signer.getPublicKey();
|
||||||
const pubkey = await signer.getPublicKey();
|
const [wallet] = await relay.query([{ authors: [pubkey], kinds: [17375] }], { signal });
|
||||||
const [wallet] = await store.query([{ authors: [pubkey], kinds: [17375] }], { signal });
|
|
||||||
|
|
||||||
if (wallet) {
|
if (wallet) {
|
||||||
let decryptedContent: string;
|
let decryptedContent: string;
|
||||||
try {
|
try {
|
||||||
decryptedContent = await signer.nip44.decrypt(pubkey, wallet.content);
|
decryptedContent = await user.signer.nip44.decrypt(pubkey, wallet.content);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logi({
|
logi({
|
||||||
level: 'error',
|
level: 'error',
|
||||||
|
|
@ -68,7 +62,7 @@ export const swapNutzapsMiddleware: MiddlewareHandler<
|
||||||
}
|
}
|
||||||
const p2pk = getPublicKey(stringToBytes('hex', privkey));
|
const p2pk = getPublicKey(stringToBytes('hex', privkey));
|
||||||
|
|
||||||
const [nutzapInformation] = await store.query([{ authors: [pubkey], kinds: [10019] }], { signal });
|
const [nutzapInformation] = await relay.query([{ authors: [pubkey], kinds: [10019] }], { signal });
|
||||||
if (!nutzapInformation) {
|
if (!nutzapInformation) {
|
||||||
return c.json({ error: 'You need to have a nutzap information event so we can get the mints.' }, 400);
|
return c.json({ error: 'You need to have a nutzap information event so we can get the mints.' }, 400);
|
||||||
}
|
}
|
||||||
|
|
@ -88,14 +82,14 @@ export const swapNutzapsMiddleware: MiddlewareHandler<
|
||||||
|
|
||||||
const nutzapsFilter: NostrFilter = { kinds: [9321], '#p': [pubkey], '#u': mints };
|
const nutzapsFilter: NostrFilter = { kinds: [9321], '#p': [pubkey], '#u': mints };
|
||||||
|
|
||||||
const [nutzapHistory] = await store.query([{ kinds: [7376], authors: [pubkey] }], { signal });
|
const [nutzapHistory] = await relay.query([{ kinds: [7376], authors: [pubkey] }], { signal });
|
||||||
if (nutzapHistory) {
|
if (nutzapHistory) {
|
||||||
nutzapsFilter.since = nutzapHistory.created_at;
|
nutzapsFilter.since = nutzapHistory.created_at;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mintsToProofs: { [key: string]: { proofs: Proof[]; redeemed: string[][] } } = {};
|
const mintsToProofs: { [key: string]: { proofs: Proof[]; redeemed: string[][] } } = {};
|
||||||
|
|
||||||
const nutzaps = await store.query([nutzapsFilter], { signal });
|
const nutzaps = await relay.query([nutzapsFilter], { signal });
|
||||||
|
|
||||||
for (const event of nutzaps) {
|
for (const event of nutzaps) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -154,7 +148,7 @@ export const swapNutzapsMiddleware: MiddlewareHandler<
|
||||||
|
|
||||||
const unspentProofs = await createEvent({
|
const unspentProofs = await createEvent({
|
||||||
kind: 7375,
|
kind: 7375,
|
||||||
content: await signer.nip44.encrypt(
|
content: await user.signer.nip44.encrypt(
|
||||||
pubkey,
|
pubkey,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
mint,
|
mint,
|
||||||
|
|
@ -169,7 +163,7 @@ export const swapNutzapsMiddleware: MiddlewareHandler<
|
||||||
|
|
||||||
await createEvent({
|
await createEvent({
|
||||||
kind: 7376,
|
kind: 7376,
|
||||||
content: await signer.nip44.encrypt(
|
content: await user.signer.nip44.encrypt(
|
||||||
pubkey,
|
pubkey,
|
||||||
JSON.stringify([
|
JSON.stringify([
|
||||||
['direction', 'in'],
|
['direction', 'in'],
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,16 @@ import { purifyEvent } from '@/utils/purify.ts';
|
||||||
type EventStub = TypeFest.SetOptional<EventTemplate, 'content' | 'created_at' | 'tags'>;
|
type EventStub = TypeFest.SetOptional<EventTemplate, 'content' | 'created_at' | 'tags'>;
|
||||||
|
|
||||||
/** Publish an event through the pipeline. */
|
/** Publish an event through the pipeline. */
|
||||||
async function createEvent(t: EventStub, c: Context): Promise<NostrEvent> {
|
async function createEvent(t: EventStub, c: AppContext): Promise<NostrEvent> {
|
||||||
const signer = c.get('signer');
|
const { user } = c.var;
|
||||||
|
|
||||||
if (!signer) {
|
if (!user) {
|
||||||
throw new HTTPException(401, {
|
throw new HTTPException(401, {
|
||||||
res: c.json({ error: 'No way to sign Nostr event' }, 401),
|
res: c.json({ error: 'No way to sign Nostr event' }, 401),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const event = await signer.signEvent({
|
const event = await user.signer.signEvent({
|
||||||
content: '',
|
content: '',
|
||||||
created_at: nostrNow(),
|
created_at: nostrNow(),
|
||||||
tags: [],
|
tags: [],
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue