mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
test: PUT '/api/v1/ditto/cashu/wallet' endpoint
This commit is contained in:
parent
b74a0ffac0
commit
1ff6511b39
1 changed files with 91 additions and 12 deletions
|
|
@ -1,26 +1,105 @@
|
||||||
// deno-lint-ignore-file require-await
|
import { Env as HonoEnv, Hono } from '@hono/hono';
|
||||||
import { NSecSigner } from '@nostrify/nostrify';
|
import { NostrSigner, NSchema as n, NSecSigner, NStore } from '@nostrify/nostrify';
|
||||||
import { assertEquals } from '@std/assert';
|
import { generateSecretKey, getPublicKey } from 'nostr-tools';
|
||||||
import { generateSecretKey } from 'nostr-tools';
|
import { bytesToString, stringToBytes } from '@scure/base';
|
||||||
|
import { assertEquals, assertExists } from '@std/assert';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { createTestDB } from '@/test.ts';
|
import { createTestDB } from '@/test.ts';
|
||||||
|
|
||||||
import cashuApp from './cashu.ts';
|
import cashuApp from '@/controllers/api/cashu.ts';
|
||||||
|
|
||||||
Deno.test('PUT /wallet', async () => {
|
interface AppEnv extends HonoEnv {
|
||||||
|
Variables: {
|
||||||
|
/** Signer to get the logged-in user's pubkey, relays, and to sign events. */
|
||||||
|
signer: NostrSigner;
|
||||||
|
/** Storage for the user, might filter out unwanted content. */
|
||||||
|
store: NStore;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Deno.test('PUT /wallet must be successful', {
|
||||||
|
sanitizeOps: false, // postgres.js calls 'setTimeout' without calling 'clearTimeout'
|
||||||
|
sanitizeResources: false, // postgres.js calls 'setTimeout' without calling 'clearTimeout'
|
||||||
|
}, async () => {
|
||||||
await using db = await createTestDB();
|
await using db = await createTestDB();
|
||||||
const store = db.store;
|
const store = db.store;
|
||||||
|
|
||||||
const sk = generateSecretKey();
|
const sk = generateSecretKey();
|
||||||
const signer = new NSecSigner(sk);
|
const signer = new NSecSigner(sk);
|
||||||
|
const nostrPrivateKey = bytesToString('hex', sk);
|
||||||
|
|
||||||
const app = cashuApp.use(
|
const expectedResponseSchema = z.object({
|
||||||
'*',
|
pubkey_p2pk: n.id(),
|
||||||
async (c) => c.set('store', store),
|
mints: z.array(z.string()).nonempty(),
|
||||||
async (c) => c.set('signer', signer),
|
relays: z.array(z.string()).nonempty(),
|
||||||
);
|
balance: z.number(),
|
||||||
|
});
|
||||||
|
|
||||||
const response = await app.request('/wallet', { method: 'PUT' });
|
const app = new Hono<AppEnv>().use(
|
||||||
|
async (c, next) => {
|
||||||
|
c.set('signer', signer);
|
||||||
|
await next();
|
||||||
|
},
|
||||||
|
async (c, next) => {
|
||||||
|
c.set('store', store);
|
||||||
|
await next();
|
||||||
|
},
|
||||||
|
).route('/', cashuApp);
|
||||||
|
|
||||||
|
const response = await app.request('/wallet', {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: [['content-type', 'application/json']],
|
||||||
|
body: JSON.stringify({
|
||||||
|
mints: [
|
||||||
|
'https://houston.mint.com',
|
||||||
|
'https://houston.mint.com', // duplicate on purpose
|
||||||
|
'https://cuiaba.mint.com',
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
assertEquals(response.status, 200);
|
assertEquals(response.status, 200);
|
||||||
|
|
||||||
|
const pubkey = await signer.getPublicKey();
|
||||||
|
|
||||||
|
const [wallet] = await store.query([{ authors: [pubkey], kinds: [17375] }]);
|
||||||
|
|
||||||
|
assertExists(wallet);
|
||||||
|
assertEquals(wallet.kind, 17375);
|
||||||
|
|
||||||
|
const { data, success } = expectedResponseSchema.safeParse(await response.json());
|
||||||
|
|
||||||
|
assertEquals(success, true);
|
||||||
|
if (!data) return; // get rid of typescript error possibly undefined
|
||||||
|
|
||||||
|
const decryptedContent: string[][] = JSON.parse(await signer.nip44.decrypt(pubkey, wallet.content));
|
||||||
|
|
||||||
|
const privkey = decryptedContent.find(([value]) => value === 'privkey')?.[1]!;
|
||||||
|
const p2pk = getPublicKey(stringToBytes('hex', privkey));
|
||||||
|
|
||||||
|
assertEquals(nostrPrivateKey !== privkey, true);
|
||||||
|
|
||||||
|
assertEquals(data.pubkey_p2pk, p2pk);
|
||||||
|
assertEquals(data.mints, [
|
||||||
|
'https://houston.mint.com',
|
||||||
|
'https://cuiaba.mint.com',
|
||||||
|
]);
|
||||||
|
assertEquals(data.relays, [
|
||||||
|
'ws://localhost:4036/relay',
|
||||||
|
]);
|
||||||
|
assertEquals(data.balance, 0);
|
||||||
|
|
||||||
|
const [nutzap_info] = await store.query([{ authors: [pubkey], kinds: [10019] }]);
|
||||||
|
|
||||||
|
assertExists(nutzap_info);
|
||||||
|
assertEquals(nutzap_info.kind, 10019);
|
||||||
|
assertEquals(nutzap_info.tags.length, 4);
|
||||||
|
|
||||||
|
const nutzap_p2pk = nutzap_info.tags.find(([value]) => value === 'pubkey')?.[1]!;
|
||||||
|
|
||||||
|
assertEquals(nutzap_p2pk, p2pk);
|
||||||
|
assertEquals([nutzap_info.tags.find(([name]) => name === 'relay')?.[1]!], [
|
||||||
|
'ws://localhost:4036/relay',
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue