Remove useNostrOrders composable and related Checkout page
- Delete the useNostrOrders composable as it is no longer needed. - Update MerchantStore.vue to utilize nostrmarketService for publishing orders instead of the removed composable. - Refactor market store to check the readiness of nostrmarketService instead of useNostrOrders. - Remove the Checkout.vue page, streamlining the checkout process and improving code maintainability.
This commit is contained in:
parent
e504b1f7e2
commit
36638d1080
6 changed files with 16 additions and 701 deletions
|
|
@ -1,248 +0,0 @@
|
|||
import { ref, computed, readonly } from 'vue'
|
||||
import { finalizeEvent, type EventTemplate, nip04 } from 'nostr-tools'
|
||||
import { relayHub } from '@/lib/nostr/relayHub'
|
||||
import { auth } from '@/composables/useAuth'
|
||||
import { hexToBytes } from '@/lib/utils/crypto'
|
||||
import type { Order } from '@/stores/market'
|
||||
|
||||
export function useNostrOrders() {
|
||||
// State
|
||||
const isPublishing = ref(false)
|
||||
const lastError = ref<string | null>(null)
|
||||
const publishedEvents = ref<Record<string, string>>({}) // orderId -> eventId
|
||||
|
||||
// Computed
|
||||
const isReady = computed(() => {
|
||||
return auth.isAuthenticated.value &&
|
||||
!!auth.currentUser.value?.pubkey &&
|
||||
!!auth.currentUser.value?.prvkey
|
||||
})
|
||||
|
||||
const currentUserPubkey = computed(() => auth.currentUser.value?.pubkey || '')
|
||||
const currentUserPrvkey = computed(() => auth.currentUser.value?.prvkey || '')
|
||||
|
||||
// Methods
|
||||
const validateAuth = (): { valid: boolean; error?: string } => {
|
||||
if (!auth.isAuthenticated.value) {
|
||||
return { valid: false, error: 'User not authenticated' }
|
||||
}
|
||||
|
||||
if (!currentUserPubkey.value) {
|
||||
return { valid: false, error: 'User public key not available' }
|
||||
}
|
||||
|
||||
if (!currentUserPrvkey.value) {
|
||||
return { valid: false, error: 'User private key not available' }
|
||||
}
|
||||
|
||||
// Validate key formats
|
||||
if (currentUserPubkey.value.length !== 64) {
|
||||
return { valid: false, error: 'Invalid public key format' }
|
||||
}
|
||||
|
||||
if (currentUserPrvkey.value.length !== 64) {
|
||||
return { valid: false, error: 'Invalid private key format' }
|
||||
}
|
||||
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
const createEventTemplate = (recipientPubkey: string, content: string): EventTemplate => {
|
||||
return {
|
||||
kind: 4, // Encrypted Direct Message
|
||||
tags: [['p', recipientPubkey]], // Recipient tag
|
||||
content: content,
|
||||
created_at: Math.floor(Date.now() / 1000)
|
||||
}
|
||||
}
|
||||
|
||||
const encryptOrderContent = async (order: Order, recipientPubkey: string): Promise<string> => {
|
||||
try {
|
||||
console.log('Encrypting order content:', {
|
||||
orderId: order.id,
|
||||
recipientPubkey,
|
||||
hasPrivateKey: !!currentUserPrvkey.value,
|
||||
privateKeyLength: currentUserPrvkey.value?.length
|
||||
})
|
||||
|
||||
// Validate keys
|
||||
if (!currentUserPrvkey.value || !recipientPubkey) {
|
||||
throw new Error('Missing private key or recipient public key')
|
||||
}
|
||||
|
||||
if (currentUserPrvkey.value.length !== 64) {
|
||||
throw new Error(`Invalid private key length: ${currentUserPrvkey.value.length} (expected 64)`)
|
||||
}
|
||||
|
||||
if (recipientPubkey.length !== 64) {
|
||||
throw new Error(`Invalid recipient public key length: ${recipientPubkey.length} (expected 64)`)
|
||||
}
|
||||
|
||||
// Create the order payload
|
||||
const orderPayload = {
|
||||
type: 'market_order',
|
||||
orderId: order.id,
|
||||
items: order.items,
|
||||
contactInfo: order.contactInfo,
|
||||
shippingZone: order.shippingZone,
|
||||
paymentMethod: order.paymentMethod,
|
||||
subtotal: order.subtotal,
|
||||
shippingCost: order.shippingCost,
|
||||
total: order.total,
|
||||
currency: order.currency,
|
||||
createdAt: order.createdAt,
|
||||
buyerPubkey: order.buyerPubkey
|
||||
}
|
||||
|
||||
// Convert to JSON string
|
||||
const orderJson = JSON.stringify(orderPayload)
|
||||
console.log('Order payload created:', orderPayload)
|
||||
|
||||
// Encrypt the order content using NIP-04
|
||||
const encryptedContent = await nip04.encrypt(
|
||||
hexToBytes(currentUserPrvkey.value),
|
||||
recipientPubkey,
|
||||
orderJson
|
||||
)
|
||||
|
||||
console.log('Order content encrypted successfully:', {
|
||||
originalLength: orderJson.length,
|
||||
encryptedLength: encryptedContent.length,
|
||||
encryptedPreview: encryptedContent.substring(0, 50) + '...'
|
||||
})
|
||||
|
||||
return encryptedContent
|
||||
} catch (error) {
|
||||
console.error('Failed to encrypt order content:', error)
|
||||
throw new Error('Failed to encrypt order content')
|
||||
}
|
||||
}
|
||||
|
||||
const publishOrderEvent = async (order: Order, recipientPubkey: string): Promise<{ id: string; sig: string }> => {
|
||||
try {
|
||||
// Validate authentication
|
||||
const authValidation = validateAuth()
|
||||
if (!authValidation.valid) {
|
||||
throw new Error(authValidation.error)
|
||||
}
|
||||
|
||||
// Set publishing state
|
||||
isPublishing.value = true
|
||||
lastError.value = null
|
||||
|
||||
// Encrypt the order content
|
||||
const encryptedContent = await encryptOrderContent(order, recipientPubkey)
|
||||
|
||||
// Create event template
|
||||
const eventTemplate = createEventTemplate(recipientPubkey, encryptedContent)
|
||||
|
||||
// Finalize the event (sign and generate ID)
|
||||
const event = finalizeEvent(eventTemplate, hexToBytes(currentUserPrvkey.value))
|
||||
|
||||
// Publish via relay hub
|
||||
await relayHub.publishEvent(event)
|
||||
|
||||
// Store the published event
|
||||
publishedEvents.value[order.id] = event.id
|
||||
|
||||
console.log('Order event published successfully:', {
|
||||
orderId: order.id,
|
||||
eventId: event.id,
|
||||
recipient: recipientPubkey,
|
||||
timestamp: new Date().toISOString()
|
||||
})
|
||||
|
||||
return { id: event.id, sig: event.sig }
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'
|
||||
lastError.value = errorMessage
|
||||
console.error('Failed to publish order event:', error)
|
||||
throw new Error(`Failed to publish order: ${errorMessage}`)
|
||||
} finally {
|
||||
isPublishing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const getPublishedEventId = (orderId: string): string | undefined => {
|
||||
return publishedEvents.value[orderId]
|
||||
}
|
||||
|
||||
const clearError = () => {
|
||||
lastError.value = null
|
||||
}
|
||||
|
||||
const reset = () => {
|
||||
isPublishing.value = false
|
||||
lastError.value = null
|
||||
publishedEvents.value = {}
|
||||
}
|
||||
|
||||
const testEncryption = async (): Promise<boolean> => {
|
||||
try {
|
||||
if (!isReady.value) {
|
||||
console.log('Nostr not ready for testing')
|
||||
return false
|
||||
}
|
||||
|
||||
const testMessage = 'Hello, this is a test message for NIP-04 encryption!'
|
||||
const testRecipient = currentUserPubkey.value // Encrypt to ourselves for testing
|
||||
|
||||
console.log('Testing NIP-04 encryption with:', {
|
||||
message: testMessage,
|
||||
recipient: testRecipient,
|
||||
sender: currentUserPubkey.value
|
||||
})
|
||||
|
||||
// Encrypt
|
||||
const encrypted = await nip04.encrypt(
|
||||
hexToBytes(currentUserPrvkey.value),
|
||||
testRecipient,
|
||||
testMessage
|
||||
)
|
||||
|
||||
console.log('Test message encrypted:', encrypted)
|
||||
|
||||
// Decrypt
|
||||
const decrypted = await nip04.decrypt(
|
||||
currentUserPrvkey.value,
|
||||
currentUserPubkey.value,
|
||||
encrypted
|
||||
)
|
||||
|
||||
console.log('Test message decrypted:', decrypted)
|
||||
|
||||
const success = decrypted === testMessage
|
||||
console.log('NIP-04 test result:', success ? 'PASSED' : 'FAILED')
|
||||
|
||||
return success
|
||||
} catch (error) {
|
||||
console.error('NIP-04 test failed:', error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
// State
|
||||
isPublishing: readonly(isPublishing),
|
||||
lastError: readonly(lastError),
|
||||
publishedEvents: readonly(publishedEvents),
|
||||
|
||||
// Computed
|
||||
isReady,
|
||||
currentUserPubkey,
|
||||
currentUserPrvkey,
|
||||
|
||||
// Methods
|
||||
validateAuth,
|
||||
createEventTemplate,
|
||||
encryptOrderContent,
|
||||
publishOrderEvent,
|
||||
getPublishedEventId,
|
||||
clearError,
|
||||
reset,
|
||||
testEncryption
|
||||
}
|
||||
}
|
||||
|
||||
// Export singleton instance
|
||||
export const nostrOrders = useNostrOrders()
|
||||
Loading…
Add table
Add a link
Reference in a new issue