Refactor market components for improved structure and functionality

- Update imports in DashboardOverview.vue to use relative paths for better module organization.
- Modify OrderHistory.vue to replace 'lightningInvoice' with 'paymentRequest' for consistency in payment handling.
- Enhance order event handling in useMarket.ts by adding subscription and decryption logic for order-related DMs.
- Update nostrmarketService.ts to use relative imports, ensuring consistency across the module.
- Introduce error handling and logging for order updates, improving the robustness of the market module.
This commit is contained in:
padreug 2025-09-05 04:38:51 +02:00
parent 36638d1080
commit f5ea2a8d5e
4 changed files with 110 additions and 12 deletions

View file

@ -215,11 +215,11 @@
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useMarketStore } from '@/stores/market'
import { useMarketStore } from '../stores/market'
import { useAuth } from '@/composables/useAuth'
import { useMarket } from '@/composables/useMarket'
import { useMarket } from '../composables/useMarket'
// import { useOrderEvents } from '@/composables/useOrderEvents' // TODO: Move to market module
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'

View file

@ -106,7 +106,7 @@
</div>
<!-- Payment Section -->
<div v-if="order.lightningInvoice" class="mb-4 p-4 bg-muted/50 border border-border rounded-lg">
<div v-if="order.paymentRequest" class="mb-4 p-4 bg-muted/50 border border-border rounded-lg">
<div class="flex items-center justify-between mb-3">
<div class="flex items-center gap-2">
<Zap class="w-4 h-4 text-yellow-500" />
@ -127,9 +127,9 @@
Payment Request
</label>
<div class="flex items-center gap-2">
<input :value="order.lightningInvoice?.bolt11 || ''" readonly disabled
<input :value="order.paymentRequest || ''" readonly disabled
class="flex-1 font-mono text-xs bg-muted border border-input rounded-md px-3 py-1 text-foreground" />
<Button @click="copyPaymentRequest(order.lightningInvoice?.bolt11 || '')" variant="outline" size="sm">
<Button @click="copyPaymentRequest(order.paymentRequest || '')" variant="outline" size="sm">
<Copy class="w-3 h-3" />
</Button>
</div>
@ -137,8 +137,8 @@
<!-- Payment Actions -->
<div class="flex gap-2">
<Button @click="openLightningWallet(order.lightningInvoice?.bolt11 || '')" variant="default" size="sm"
class="flex-1" :disabled="!order.lightningInvoice?.bolt11">
<Button @click="openLightningWallet(order.paymentRequest || '')" variant="default" size="sm"
class="flex-1" :disabled="!order.paymentRequest">
<Zap class="w-3 h-3 mr-1" />
Pay with Lightning
</Button>
@ -244,7 +244,15 @@ const router = useRouter()
const marketStore = useMarketStore()
const relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
// const orderEvents = useOrderEvents() // TODO: Move to market module
const orderEvents = { isSubscribed: ref(false), subscribeToOrderEvents: () => {}, cleanup: () => {} } // Temporary mock
const orderEvents = {
isSubscribed: ref(false),
subscribeToOrderEvents: () => {},
cleanup: () => {},
initialize: () => {
console.log('OrderEvents mock initialize called')
orderEvents.isSubscribed.value = true
}
} // Temporary mock
// Local state
const statusFilter = ref('')

View file

@ -3,6 +3,8 @@ import { useNostrStore } from '@/stores/nostr'
import { useMarketStore } from '../stores/market'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
import { config } from '@/lib/config'
import { nostrmarketService } from '../services/nostrmarketService'
import { nip04 } from 'nostr-tools'
// Nostr event kinds for market functionality
const MARKET_EVENT_KINDS = {
@ -333,6 +335,89 @@ export function useMarket() {
}
}
// Subscribe to order-related DMs (payment requests, status updates)
const subscribeToOrderUpdates = (): (() => void) | null => {
try {
// TODO: Confirm if this should use nostrStore.account?.pubkey or authService.user.value?.pubkey
const userPubkey = nostrStore.account?.pubkey || authService.user.value?.pubkey
if (!userPubkey) {
console.warn('Cannot subscribe to order updates: no user pubkey available', {
nostrStorePubkey: nostrStore.account?.pubkey,
authServicePubkey: authService.user.value?.pubkey,
isAuthenticated: authService.isAuthenticated.value
})
return null
}
console.log('🔔 Setting up order updates subscription for user:', userPubkey.slice(0, 8))
// Subscribe to encrypted DMs directed to this user (payment requests, status updates)
const unsubscribe = relayHub.subscribe({
id: `order-updates-${userPubkey}`,
filters: [
{
kinds: [4], // Encrypted DMs
'#p': [userPubkey], // Messages directed to this user
since: Math.floor(Date.now() / 1000) - 3600 // Last hour to avoid old messages
}
],
onEvent: async (event: any) => {
await handleOrderDM(event)
}
})
return unsubscribe
} catch (error) {
console.error('Failed to subscribe to order updates:', error)
return null
}
}
// Handle incoming order DMs (payment requests, status updates)
const handleOrderDM = async (event: any) => {
try {
console.log('🔔 Received order-related DM:', event.id, 'from:', event.pubkey.slice(0, 8))
// TODO: Confirm if this should use nostrStore.account?.pubkey or authService.user.value?.pubkey
const userPubkey = nostrStore.account?.pubkey || authService.user.value?.pubkey
const userPrivkey = nostrStore.account?.privkey || authService.user.value?.prvkey
if (!userPrivkey) {
console.warn('Cannot decrypt DM: no user private key available', {
nostrStorePrivkey: !!nostrStore.account?.privkey,
authServicePrivkey: !!authService.user.value?.prvkey
})
return
}
console.log('🔓 Attempting to decrypt DM with private key available')
// Decrypt the DM content
const decryptedContent = await nip04.decrypt(userPrivkey, event.pubkey, event.content)
console.log('🔓 Decrypted DM content:', decryptedContent)
// Parse the decrypted content as JSON
const messageData = JSON.parse(decryptedContent)
console.log('📨 Parsed message data:', messageData)
// Handle different types of messages
switch (messageData.type) {
case 1: // Payment request
console.log('💰 Processing payment request')
await nostrmarketService.handlePaymentRequest(messageData)
break
case 2: // Order status update
console.log('📦 Processing order status update')
await nostrmarketService.handleOrderStatusUpdate(messageData)
break
default:
console.log('❓ Unknown message type:', messageData.type)
}
} catch (error) {
console.error('Failed to handle order DM:', error)
}
}
// Handle incoming market events
const handleMarketEvent = (event: any) => {
// Process market event
@ -494,6 +579,10 @@ export function useMarket() {
// Subscribe to updates
console.log('🛒 Subscribing to market updates...')
subscribeToMarketUpdates()
// Subscribe to order-related DMs
console.log('🛒 Subscribing to order updates...')
subscribeToOrderUpdates()
} catch (err) {
console.error('🛒 Failed to connect to market:', err)
@ -540,6 +629,7 @@ export function useMarket() {
processPendingProducts,
publishProduct,
publishStall,
subscribeToMarketUpdates
subscribeToMarketUpdates,
subscribeToOrderUpdates
}
}

View file

@ -330,7 +330,7 @@ export class NostrmarketService {
}
// Update the order in the store with payment request
const { useMarketStore } = await import('@/stores/market')
const { useMarketStore } = await import('../stores/market')
const marketStore = useMarketStore()
const order = Object.values(marketStore.orders).find(o =>
@ -393,7 +393,7 @@ export class NostrmarketService {
shipped: statusUpdate.shipped
})
const { useMarketStore } = await import('@/stores/market')
const { useMarketStore } = await import('../stores/market')
const marketStore = useMarketStore()
const order = Object.values(marketStore.orders).find(o =>