mirror of
https://github.com/aljazceru/hypergolic.git
synced 2025-12-19 14:34:20 +01:00
problem: zap handling is messy
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
|
||||
function zap() {
|
||||
let z = new NDKZap({ndk:$ndk, zappedEvent:rocket, zappedUser: rocket.author})
|
||||
z.createZapRequest(1000, `Purchase of ${product.getMatchingTags("name")[0][1]} from ${rocket.dTag}`, [["e", product.id]]).then(invoice=>{
|
||||
z.createZapRequest(1000, `Purchase of ${product.getMatchingTags("name")[0][1]} from ${rocket.dTag}`, [["product", product.id]]).then(invoice=>{
|
||||
if (invoice) {
|
||||
requestProvider().then((webln)=>{
|
||||
webln.sendPayment(invoice).then((response)=>{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import * as Card from '@/components/ui/card';
|
||||
import * as Table from '@/components/ui/table';
|
||||
import type { RocketProduct } from '@/event_helpers/rockets';
|
||||
import { ZapPurchase, type RocketProduct } from '@/event_helpers/rockets';
|
||||
import { unixToRelativeTime } from '@/helpers';
|
||||
import { ndk } from '@/ndk';
|
||||
import { NDKEvent } from '@nostr-dev-kit/ndk';
|
||||
@@ -33,59 +33,18 @@
|
||||
});
|
||||
});
|
||||
|
||||
let newZaps = derived(zaps, ($zaps) => {
|
||||
let zapMap = new Map<string, NDKEvent>();
|
||||
let purchases = derived(zaps, ($zaps) => {
|
||||
let zapMap = new Map<string, ZapPurchase>();
|
||||
for (let z of $zaps) {
|
||||
if (!product.Purchases.get(z.id)) {
|
||||
let zapRequestEvent = getZapRequest(z);
|
||||
if (zapRequestEvent) {
|
||||
for (let zapEtag of zapRequestEvent.getMatchingTags('e')) {
|
||||
if (zapEtag && zapEtag.length > 1 && zapEtag[1].length == 64) {
|
||||
if (product.ID == zapEtag[1]) {
|
||||
//todo: validate zapper pubkey is from a LSP specified in rocket
|
||||
//todo: validate amount is same as product amount in rocket
|
||||
zapMap.set(z.id, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let zapPurchase = new ZapPurchase(z);
|
||||
if (zapPurchase.Valid(rocket)) {
|
||||
zapMap.set(zapPurchase.ZapReceipt.id, zapPurchase);
|
||||
}
|
||||
}
|
||||
return zapMap;
|
||||
});
|
||||
|
||||
function getZapRequest(zapReceipt: NDKEvent): NDKEvent | undefined {
|
||||
let zapRequestEvent: NDKEvent | undefined = undefined;
|
||||
let zapRequest = zapReceipt.getMatchingTags('description');
|
||||
if (zapRequest.length == 1) {
|
||||
let zapRequestJSON = JSON.parse(zapRequest[0][1]);
|
||||
if (zapRequestJSON) {
|
||||
zapRequestEvent = new NDKEvent($ndk, zapRequestJSON);
|
||||
}
|
||||
}
|
||||
return zapRequestEvent;
|
||||
}
|
||||
|
||||
function getPayerPubkey(zapReceipt:NDKEvent):string|undefined {
|
||||
let pubkey = undefined
|
||||
let zreq = getZapRequest(zapReceipt)
|
||||
if (zreq && zreq.author.pubkey.length == 64) {
|
||||
pubkey = zreq.author.pubkey
|
||||
}
|
||||
return pubkey
|
||||
}
|
||||
|
||||
function getZapAmount(zapRequest?: NDKEvent): number {
|
||||
let amount = 0;
|
||||
let amountTag = zapRequest?.getMatchingTags('amount');
|
||||
if (amountTag?.length == 1) {
|
||||
amount = parseInt(amountTag[0][1], 10);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
//fetch payments from rocket::product and live zaps and make a store Map<productID, []payments>
|
||||
//todo: validate zaps against product, publish store of all successful payments including those already in rocket. Publish another store with successful payments that are not yet included in rocket state so we can update the state and republish.
|
||||
//todo: update rocket event with confirmed zaps if we have votepower
|
||||
</script>
|
||||
|
||||
<Card.Root>
|
||||
@@ -105,29 +64,31 @@
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{#each $newZaps as [id, zapReceipt], _ (id)}
|
||||
<Table.Row on:click={()=>{console.log(getZapRequest(zapReceipt)?.rawEvent())}} class="bg-accent">
|
||||
{#each $purchases as [id, purchase], _ (id)}
|
||||
<Table.Row
|
||||
on:click={() => {
|
||||
console.log(purchase.ZapReceipt.rawEvent());
|
||||
}}
|
||||
class="bg-accent"
|
||||
>
|
||||
<Table.Cell>
|
||||
<div class="flex flex-nowrap">
|
||||
<div class=" hidden">{getZapRequest(zapReceipt)?.author.pubkey}</div>
|
||||
|
||||
<Avatar
|
||||
ndk={$ndk}
|
||||
pubkey={getPayerPubkey(zapReceipt)}
|
||||
pubkey={purchase.BuyerPubkey}
|
||||
class="h-10 w-10 flex-none rounded-full object-cover"
|
||||
/>
|
||||
<Name
|
||||
ndk={$ndk}
|
||||
pubkey={getZapRequest(zapReceipt)?.author.pubkey}
|
||||
class="inline-block truncate p-2 max-w-32"
|
||||
pubkey={purchase.BuyerPubkey}
|
||||
class="inline-block max-w-32 truncate p-2"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</Table.Cell>
|
||||
<Table.Cell class="hidden md:table-cell"
|
||||
>{getZapAmount(getZapRequest(zapReceipt)) / 1000}</Table.Cell
|
||||
<Table.Cell class="hidden md:table-cell">{purchase.Amount / 1000}</Table.Cell>
|
||||
<Table.Cell class="text-right"
|
||||
>{unixToRelativeTime(purchase.ZapReceipt.created_at * 1000)}</Table.Cell
|
||||
>
|
||||
<Table.Cell class="text-right">{unixToRelativeTime(zapReceipt.created_at*1000)}</Table.Cell>
|
||||
</Table.Row>
|
||||
{/each}
|
||||
</Table.Body>
|
||||
|
||||
@@ -1,59 +1,4 @@
|
||||
import { NDKEvent, type NDKTag } from "@nostr-dev-kit/ndk";
|
||||
import type NDKSvelte from "@nostr-dev-kit/ndk-svelte";
|
||||
|
||||
export function getZapData(ndk:NDKSvelte, zap: NDKEvent, rocket:NDKEvent) {
|
||||
let productPrice = 0;
|
||||
let zapAmount = 0;
|
||||
let productID: string | undefined = undefined;
|
||||
let buyerPubkey: string | undefined = undefined;
|
||||
let zapRequest: NDKEvent | undefined = undefined;
|
||||
|
||||
let desc = zap.getMatchingTags('description');
|
||||
if (desc && desc.length == 1 && rocket) {
|
||||
zapRequest = new NDKEvent(ndk, JSON.parse(desc[0][1]));
|
||||
let zapRequestETags = zapRequest.getMatchingTags('e');
|
||||
|
||||
if (zapRequestETags && zapRequestETags.length > 0) {
|
||||
for (let productIDfromZapRequest of zapRequestETags) {
|
||||
if (productIDfromZapRequest.length > 1) {
|
||||
let productsInRocket = getMapOfProductsFromRocket(rocket);
|
||||
if (productsInRocket.size > 0) {
|
||||
productID = productIDfromZapRequest[1];
|
||||
if (productID.length == 64) {
|
||||
let productDataFromRocket = productsInRocket.get(productID);
|
||||
if (productDataFromRocket) {
|
||||
productPrice = productDataFromRocket.Price;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let amount = zapRequest.getMatchingTags('amount');
|
||||
if (amount && amount.length == 1) {
|
||||
if (amount[0].length == 2) {
|
||||
zapAmount = parseInt(amount[0][1], 10);
|
||||
}
|
||||
}
|
||||
buyerPubkey = zapRequest.author.pubkey;
|
||||
}
|
||||
let success = false;
|
||||
if (zapRequest && productID && buyerPubkey && productPrice && zapAmount) {
|
||||
if (zapAmount >= productPrice && productID.length == 64 && buyerPubkey.length == 64) {
|
||||
success = true;
|
||||
return {
|
||||
productPrice: productPrice,
|
||||
zapAmount: zapAmount,
|
||||
productID: productID,
|
||||
buyerPubkey: buyerPubkey,
|
||||
zapReceipt: zap.id
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
console.log('invalid product payment zap found:', zapRequest?.rawEvent());
|
||||
}
|
||||
}
|
||||
import { NDKEvent, type NDKTag } from '@nostr-dev-kit/ndk';
|
||||
|
||||
export class RocketProduct {
|
||||
ID: string;
|
||||
@@ -76,6 +21,7 @@ export class RocketProduct {
|
||||
}
|
||||
}
|
||||
|
||||
//ProductPayment takes the payment string from a product tag on a rocket event
|
||||
export class ProductPayment {
|
||||
ZapID: string;
|
||||
BuyerPubkey: string;
|
||||
@@ -96,3 +42,88 @@ export function getMapOfProductsFromRocket(rocket: NDKEvent): Map<string, Rocket
|
||||
}
|
||||
return productIDs;
|
||||
}
|
||||
|
||||
export class ZapPurchase {
|
||||
Amount: number;
|
||||
ProductID: string;
|
||||
BuyerPubkey: string;
|
||||
ZapReceipt: NDKEvent;
|
||||
ZapRequest(): NDKEvent | undefined {
|
||||
return getZapRequest(this.ZapReceipt);
|
||||
}
|
||||
IncludedInRocketState(rocket: NDKEvent): boolean {
|
||||
let thisProduct = this.ProductFromRocket(rocket);
|
||||
if (thisProduct) {
|
||||
return thisProduct.Purchases.get(this.ZapReceipt.id) ? true : false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ProductFromRocket(rocket: NDKEvent): RocketProduct | undefined {
|
||||
let productsInRocket = getMapOfProductsFromRocket(rocket);
|
||||
return productsInRocket.get(this.ProductID);
|
||||
}
|
||||
ValidAmount(rocket: NDKEvent): boolean {
|
||||
if (this.Amount < 1) {
|
||||
return false;
|
||||
}
|
||||
if (this.IncludedInRocketState(rocket)) {
|
||||
return true;
|
||||
}
|
||||
let product = this.ProductFromRocket(rocket);
|
||||
if (product && this.Amount >= product.Price) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Valid(rocket: NDKEvent): boolean {
|
||||
//todo: validate zapper pubkey is from a LSP specified in rocket
|
||||
let valid = true;
|
||||
if (!this.ValidAmount(rocket)) {
|
||||
valid = false;
|
||||
}
|
||||
if (!this.ProductID) {
|
||||
valid = false;
|
||||
}
|
||||
if (this.ProductID && this.ProductID.length != 64) {
|
||||
valid = false;
|
||||
}
|
||||
if (this.BuyerPubkey.length != 64) {
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
constructor(zapReceipt: NDKEvent) {
|
||||
this.ZapReceipt = zapReceipt;
|
||||
this.Amount = getZapAmount(this.ZapRequest());
|
||||
let zapRequest = this.ZapRequest();
|
||||
if (zapRequest) {
|
||||
this.BuyerPubkey = zapRequest.pubkey;
|
||||
let products = zapRequest.getMatchingTags('product');
|
||||
if (products.length == 1 && products[0] && products[0][1] && products[0][1].length == 64) {
|
||||
this.ProductID = products[0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getZapRequest(zapReceipt: NDKEvent): NDKEvent | undefined {
|
||||
let zapRequestEvent: NDKEvent | undefined = undefined;
|
||||
let zapRequest = zapReceipt.getMatchingTags('description');
|
||||
if (zapRequest.length == 1) {
|
||||
let zapRequestJSON = JSON.parse(zapRequest[0][1]);
|
||||
if (zapRequestJSON) {
|
||||
zapRequestEvent = new NDKEvent(zapReceipt.ndk, zapRequestJSON);
|
||||
}
|
||||
}
|
||||
return zapRequestEvent;
|
||||
}
|
||||
|
||||
function getZapAmount(zapRequest?: NDKEvent): number {
|
||||
let amount = 0;
|
||||
let amountTag = zapRequest?.getMatchingTags('amount');
|
||||
if (amountTag?.length == 1) {
|
||||
amount = parseInt(amountTag[0][1], 10);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
@@ -74,13 +74,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
class ZapPurchase {
|
||||
Amount: number;
|
||||
ProductID: string;
|
||||
Buyer: string;
|
||||
ZapReceiptID: string;
|
||||
constructor(zapReceipt: NDKEvent) {}
|
||||
}
|
||||
|
||||
|
||||
//todo: check that this zap is not already included in the payment JSON for the product
|
||||
//todo: list purchases on the rocket page (from product tags, as well as zap receipts that aren't yet included). Deduct total products available if not 0.
|
||||
|
||||
Reference in New Issue
Block a user