mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 11:29:46 +00:00
checkpoint: implement swapNutzapsToWalletController
This commit is contained in:
parent
236a9284ca
commit
870847127b
2 changed files with 74 additions and 0 deletions
|
|
@ -50,6 +50,7 @@ import {
|
||||||
nameRequestController,
|
nameRequestController,
|
||||||
nameRequestsController,
|
nameRequestsController,
|
||||||
statusZapSplitsController,
|
statusZapSplitsController,
|
||||||
|
swapNutzapsToWalletController,
|
||||||
updateInstanceController,
|
updateInstanceController,
|
||||||
updateZapSplitsController,
|
updateZapSplitsController,
|
||||||
} from '@/controllers/api/ditto.ts';
|
} from '@/controllers/api/ditto.ts';
|
||||||
|
|
@ -409,6 +410,7 @@ app.get('/api/v1/ditto/statuses/:id{[0-9a-f]{64}}/zapped_by', zappedByController
|
||||||
|
|
||||||
app.post('/api/v1/ditto/wallet/create', requireSigner, createCashuWalletController);
|
app.post('/api/v1/ditto/wallet/create', requireSigner, createCashuWalletController);
|
||||||
app.post('/api/v1/ditto/nutzap_information/create', requireSigner, createNutzapInformationController);
|
app.post('/api/v1/ditto/nutzap_information/create', requireSigner, createNutzapInformationController);
|
||||||
|
app.get('/api/v1/ditto/nutzap/swap_to_wallet', requireSigner, swapNutzapsToWalletController);
|
||||||
|
|
||||||
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, requireRole('admin'), adminReportsController);
|
||||||
|
|
|
||||||
|
|
@ -479,3 +479,75 @@ export const createNutzapInformationController: AppController = async (c) => {
|
||||||
|
|
||||||
return c.json(201);
|
return c.json(201);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps all nutzaps (NIP-61) to the user's wallet (NIP-60)
|
||||||
|
*/
|
||||||
|
export const swapNutzapsToWalletController: AppController = async (c) => {
|
||||||
|
const signer = c.get('signer')!;
|
||||||
|
const store = c.get('store');
|
||||||
|
const pubkey = await signer.getPublicKey();
|
||||||
|
const { signal } = c.req.raw;
|
||||||
|
|
||||||
|
const nip44 = signer.nip44;
|
||||||
|
if (!nip44) {
|
||||||
|
return c.json({ error: 'Signer does not have nip 44.' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [wallet] = await store.query([{ authors: [pubkey], kinds: [17375] }], { signal });
|
||||||
|
if (!wallet) {
|
||||||
|
return c.json({ error: 'You need to have a wallet to swap the nutzaps into it.' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
let decryptedContent: string;
|
||||||
|
try {
|
||||||
|
decryptedContent = await nip44.decrypt(pubkey, wallet.content);
|
||||||
|
} catch (e) {
|
||||||
|
logi({ level: 'error', ns: 'ditto.api', id: wallet.id, kind: wallet.kind, error: errorJson(e) });
|
||||||
|
return c.json({ error: 'Could not decrypt wallet content.' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentTags: string[][];
|
||||||
|
try {
|
||||||
|
contentTags = JSON.parse(decryptedContent);
|
||||||
|
} catch {
|
||||||
|
return c.json({ error: 'Could not JSON parse the decrypted wallet content.' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const privkey = contentTags.find(([value]) => value === 'privkey')?.[1];
|
||||||
|
if (!privkey || !isNostrId(privkey)) {
|
||||||
|
return c.json({ error: 'Wallet does not contain privkey or privkey is not a valid nostr id.' }, 400);
|
||||||
|
}
|
||||||
|
const p2pk = getPublicKey(stringToBytes('hex', privkey));
|
||||||
|
|
||||||
|
const [nutzapInformation] = await store.query([{ authors: [pubkey], kinds: [10019] }], { signal });
|
||||||
|
if (!nutzapInformation) {
|
||||||
|
return c.json({ error: 'You need to have a nutzap information event so we can get the mints.' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nutzapInformationPubkey = nutzapInformation.tags.find(([name]) => name === 'pubkey')?.[1];
|
||||||
|
if (!nutzapInformationPubkey || (nutzapInformationPubkey !== p2pk)) {
|
||||||
|
return c.json({
|
||||||
|
error:
|
||||||
|
"You do not have a 'pubkey' tag in your nutzap information event or the one you have does not match the one derivated from the wallet.",
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mints = [...new Set(nutzapInformation.tags.filter(([name]) => name === 'mint').map(([_, value]) => value))];
|
||||||
|
if (mints.length < 1) {
|
||||||
|
return c.json({ error: 'You do not have any mints in your nutzap information event.' }, 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
const nutzapsFilter: NostrFilter = { kinds: [9321], '#p': [pubkey], '#u': mints };
|
||||||
|
|
||||||
|
const [nutzapHistory] = await store.query([{ kinds: [7376], authors: [pubkey] }], { signal });
|
||||||
|
if (nutzapHistory) {
|
||||||
|
nutzapsFilter.since = nutzapHistory.created_at;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nutzaps = await store.query([nutzapsFilter], { signal });
|
||||||
|
|
||||||
|
// TODO: finally start doing the swap
|
||||||
|
|
||||||
|
return c.json(201);
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue