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:
parent
36638d1080
commit
f5ea2a8d5e
4 changed files with 110 additions and 12 deletions
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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('')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue