allow purchasing time with lightning directly not just cashu (fix #9)
This commit is contained in:
parent
77a9a6842b
commit
88d9515ba6
3 changed files with 67 additions and 1 deletions
|
@ -26,6 +26,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@arx/utils": "git+ssh://git@git.arx-ccn.com:222/Arx/ts-utils#03163e9f4a07b011a28a8f97c90852ecfc806ddd",
|
||||
"@cashu/cashu-ts": "^2.1.0",
|
||||
"@gandlaf21/bc-ur": "^1.1.12",
|
||||
"@nostr-dev-kit/ndk": "^2.10.7",
|
||||
"@nostr-dev-kit/ndk-cache-dexie": "^2.5.8",
|
||||
|
|
|
@ -37,7 +37,7 @@ button, .button {
|
|||
}
|
||||
|
||||
|
||||
input[type="text"], input[type="password"] {
|
||||
input[type="text"], input[type="number"], input[type="password"] {
|
||||
background: var(--editor-bg);
|
||||
border: 1px solid var(--input-border);
|
||||
color: var(--text-primary);
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
import { TokenInfoWithMailSubscriptionDuration } from '@arx/utils';
|
||||
import TimeCountdown from '../../components/TimeCountdown.svelte';
|
||||
import { ndk } from '$lib/stores.svelte';
|
||||
import { CashuMint, CashuWallet, getEncodedTokenV4, MintQuoteState } from '@cashu/cashu-ts';
|
||||
import type { MintQuoteResponse } from '@cashu/cashu-ts';
|
||||
import Dialog from '../../components/Dialog.svelte';
|
||||
import * as qr from 'qrcode';
|
||||
|
||||
let { onReloadNeeded } = $props<{
|
||||
onReloadNeeded: () => void;
|
||||
|
@ -35,6 +39,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
let buyingWithLightning = $state(false);
|
||||
let lightningAmount = $state(21);
|
||||
let invoice = $state('');
|
||||
let invoiceQR = $state('');
|
||||
let mintQuote = $state<MintQuoteResponse | null>(null);
|
||||
|
||||
const mint = new CashuMint('https://mint.minibits.cash/Bitcoin');
|
||||
const wallet = new CashuWallet(mint);
|
||||
|
||||
async function buyWithLightning() {
|
||||
if (tokenInfo) return;
|
||||
if(!mintQuote) return;
|
||||
const mintQuoteChecked = await wallet.checkMintQuote(mintQuote.quote);
|
||||
if (mintQuoteChecked.state === MintQuoteState.PAID) {
|
||||
const proofs = await wallet.mintProofs(lightningAmount, mintQuote.quote);
|
||||
cashuTokenForBuy = getEncodedTokenV4({ mint: mint.mintUrl, proofs: proofs });
|
||||
buyingWithLightning = false;
|
||||
invoice = '';
|
||||
invoiceQR = '';
|
||||
mintQuote = null;
|
||||
try {
|
||||
tokenInfo = new TokenInfoWithMailSubscriptionDuration(cashuTokenForBuy);
|
||||
tokenInfoError = '';
|
||||
} catch (e) {
|
||||
tokenInfoError = (e as Error).message;
|
||||
}
|
||||
buyTime();
|
||||
} else
|
||||
alert('Invoice not paid yet')
|
||||
}
|
||||
|
||||
async function generateInvoice() {
|
||||
await wallet.loadMint();
|
||||
mintQuote = await wallet.createMintQuote(lightningAmount);
|
||||
invoice = mintQuote.request;
|
||||
invoiceQR = await qr.toDataURL(invoice);
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
try {
|
||||
tokenInfo = new TokenInfoWithMailSubscriptionDuration(cashuTokenForBuy);
|
||||
|
@ -45,6 +87,28 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<Dialog bind:open={buyingWithLightning}>
|
||||
<div class="section-title">
|
||||
<h3>Buy time with lightning</h3>
|
||||
<button class="close-button" onclick={() => (buyingWithLightning = false)}>Close</button>
|
||||
</div>
|
||||
|
||||
{#if !invoice}
|
||||
<p>Enter the amount of time you want to buy (min 21 sats, 210 sats = 1 day):</p>
|
||||
|
||||
<input bind:value={lightningAmount} min="21" placeholder="Enter amount" type="number" />
|
||||
|
||||
<button onclick={generateInvoice}>Generate Invoice</button>
|
||||
{:else}
|
||||
<div style="align-items: center; display: flex; flex-direction: column;">
|
||||
<img src={invoiceQR} alt="Lightning Invoice" />
|
||||
<input disabled value={invoice} type="text" />
|
||||
<p>After payment, click the button below to add the time to your account.</p>
|
||||
<button onclick={buyWithLightning}>Add time</button>
|
||||
</div>
|
||||
{/if}
|
||||
</Dialog>
|
||||
|
||||
{#if cashuTokenForBuy !== ''}
|
||||
{#if tokenInfoError}
|
||||
<p class="error">{tokenInfoError}</p>
|
||||
|
@ -56,6 +120,7 @@
|
|||
{/if}
|
||||
|
||||
<input bind:value={cashuTokenForBuy} placeholder="Enter cashu token" type="text" />
|
||||
<button onclick={() => buyTimeForNpub.trim() ? buyingWithLightning = true : alert('Please enter a valid npub first')}>Or click here for lightning</button>
|
||||
<h4>Buy for:</h4>
|
||||
<input bind:value={buyTimeForNpub} placeholder="Enter npub" type="text" />
|
||||
<button onclick={() => (buyTimeForNpub = $ndk.activeUser.npub)}>Set to your own</button>
|
||||
|
|
Loading…
Reference in a new issue