Replace NIP-04 messaging with NIP-17 (NIP-44 + NIP-59 gift wrapping)
Modernize the entire customer-merchant communication layer from deprecated NIP-04 (kind 4, AES-256-CBC) to NIP-17 private direct messages using NIP-44 v2 encryption (ChaCha20 + HMAC-SHA256) and NIP-59 gift wrapping (rumor/seal/gift-wrap protocol). No backwards compatibility retained. New modules: - nostr/nip44.py: NIP-44 v2 encryption verified against official spec vectors - nostr/nip59.py: NIP-59 gift wrap with wrap/unwrap convenience functions - tests/: 44 unit tests for NIP-44 and NIP-59 Key changes: - Subscription filters: kind 4 → kind 1059 gift wraps - Message handler: _handle_nip04_message → _handle_gift_wrap (unwrap + route) - send_dm/reply_to_structured_dm: NIP-59 gift wrap to recipient + self-archive - Merchant model: removed NIP-04 crypto methods (decrypt/encrypt/build_dm_event) - helpers.py: removed NIP-04 functions, kept Schnorr signing + key normalization - views_api.py: consolidated DM sending through send_dm() service function Reliability improvements: - Event deduplication via bounded LRU set in NostrClient - Subscription health monitor (resubscribes after 120s of silence) - Preserved 5-minute lenient time window from prior work Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
319d5eeb04
commit
725944ae9c
13 changed files with 869 additions and 165 deletions
42
views_api.py
42
views_api.py
|
|
@ -84,6 +84,7 @@ from .services import (
|
|||
create_or_update_order_from_dm,
|
||||
reply_to_structured_dm,
|
||||
resubscribe_to_all_merchants,
|
||||
send_dm,
|
||||
sign_and_send_to_nostr,
|
||||
subscribe_to_all_merchants,
|
||||
update_merchant_to_nostr,
|
||||
|
|
@ -881,27 +882,11 @@ async def api_update_order_status(
|
|||
ensure_ascii=False,
|
||||
)
|
||||
|
||||
dm_event = merchant.build_dm_event(dm_content, order.public_key)
|
||||
|
||||
dm = PartialDirectMessage(
|
||||
event_id=dm_event.id,
|
||||
event_created_at=dm_event.created_at,
|
||||
message=dm_content,
|
||||
public_key=order.public_key,
|
||||
type=DirectMessageType.ORDER_PAID_OR_SHIPPED.value,
|
||||
)
|
||||
await create_direct_message(merchant.id, dm)
|
||||
|
||||
await nostr_client.publish_nostr_event(dm_event)
|
||||
await websocket_updater(
|
||||
merchant.id,
|
||||
json.dumps(
|
||||
{
|
||||
"type": f"dm:{dm.type}",
|
||||
"customerPubkey": order.public_key,
|
||||
"dm": dm.dict(),
|
||||
}
|
||||
),
|
||||
await send_dm(
|
||||
merchant,
|
||||
order.public_key,
|
||||
DirectMessageType.ORDER_PAID_OR_SHIPPED.value,
|
||||
dm_content,
|
||||
)
|
||||
|
||||
return order
|
||||
|
|
@ -1079,14 +1064,13 @@ async def api_create_message(
|
|||
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||
assert merchant, "Merchant cannot be found"
|
||||
|
||||
dm_event = merchant.build_dm_event(data.message, data.public_key)
|
||||
data.event_id = dm_event.id
|
||||
data.event_created_at = dm_event.created_at
|
||||
|
||||
dm = await create_direct_message(merchant.id, data)
|
||||
await nostr_client.publish_nostr_event(dm_event)
|
||||
|
||||
return dm
|
||||
dm_reply = await send_dm(
|
||||
merchant,
|
||||
data.public_key,
|
||||
data.type,
|
||||
data.message,
|
||||
)
|
||||
return dm_reply
|
||||
except AssertionError as ex:
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.BAD_REQUEST,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue