@nostr-dev-kit/ndk-wallet
Version:
83 lines (67 loc) • 2.76 kB
text/typescript
import type { Proof } from "@cashu/cashu-ts";
import type NDK from "@nostr-dev-kit/ndk";
import { NDKCashuToken, type NDKNutzap } from "@nostr-dev-kit/ndk";
import { createOutTxEvent } from "../cashu/wallet/txs.js";
import type { RedeemNutzapsOpts } from "../index.js";
import type { NDKNWCWallet } from "./index.js";
export async function redeemNutzaps(
this: NDKNWCWallet,
nutzaps: NDKNutzap[],
privkey: string,
{ cashuWallet, proofs, mint }: RedeemNutzapsOpts,
): Promise<number> {
proofs ??= nutzaps.flatMap((n) => n.proofs);
if (!cashuWallet) {
if (!mint) throw new Error("No mint provided");
cashuWallet = await this.getCashuWallet(mint);
} else {
mint = cashuWallet.mint.mintUrl;
}
const info = await this.getInfo();
if (!info.methods.includes("make_invoice")) throw new Error("This NWC wallet does not support making invoices");
// get the total amount of the proofs
const totalAvailable = proofs.reduce((acc, proof) => acc + proof.amount, 0);
let sweepAmount = totalAvailable;
while (sweepAmount > 0) {
const invoice = await this.makeInvoice(sweepAmount * 1000, "Nutzap redemption");
const meltQuote = await cashuWallet.createMeltQuote(invoice.invoice);
const totalRequired = meltQuote.amount + meltQuote.fee_reserve;
if (totalRequired > totalAvailable) {
sweepAmount -= meltQuote.fee_reserve;
continue;
}
const result = await cashuWallet.meltProofs(meltQuote, proofs, { privkey });
let change: NDKCashuToken | undefined;
if (result.change.length > 0) change = await saveChange(this.ndk, mint, result.change);
const description = `Nutzap redemption to external wallet (${this.walletId})`;
createOutTxEvent(
this.ndk,
{
pr: invoice.invoice,
paymentDescription: description,
},
{
result: { preimage: invoice.preimage },
mint: mint,
fee: meltQuote.fee_reserve,
proofsChange: { store: change?.proofs, mint },
stateUpdate: {
created: change,
},
},
this.relaySet,
{ nutzaps },
);
return sweepAmount;
}
throw new Error("Failed to redeem nutzaps");
}
async function saveChange(ndk: NDK, mint: string, change: Proof[]): Promise<NDKCashuToken | undefined> {
const totalChange = change.reduce((acc, proof) => acc + proof.amount, 0);
if (totalChange === 0) return;
const token = new NDKCashuToken(ndk);
token.mint = mint;
token.proofs = change;
token.publish();
return token;
}