feat(p2pk): implement end-to-end Cashu escrow lifecycle#512
Conversation
974d9d6 to
df6549f
Compare
|
@calvadev please check it once whenever feasible! |
|
@calvadev can you please review this pr |
@kaihere14 meanwhile please resolve the conflict! |
okay |
|
A few things before this hits real buyers: Blocking:
Follow-up:
Nits: cashuPrivkey now lives in app-wide context; the pubkeysEqual test mock is looser than the real fn; a couple of unrelated typing fixes are bundled in. |
* skip LN melt flow when P2PK escrow is active * ensure sellers receive locked ecash tokens instead of instant LN payout * preserve escrow behavior across product and cart checkout flows
- add wallet-config parser utilities - support legacy and v1 wallet config schemas - merge mints across wallet config events - load keypair from newest v1 wallet config - extend fetchCashuWallet return type with optional keys - add parser and fetch-service tests - preserve existing wallet publishing and UI behavior
- add cashuPubkey and cashuPrivkey to CashuWalletContext - extend editCashuWalletContext to accept wallet keys - propagate v1 wallet keys from fetchCashuWallet into context - preserve legacy wallet behavior with undefined keys - add fetch-service tests for context key propagation - keep wallet creation and publishing logic unchanged
- add Cashu wallet keypair generation helpers - publish WalletConfig v1 wallet events - persist wallet identities in encrypted kind 17375 events - load existing wallet identities on startup - expose generated keys through CashuWalletContext - preserve backward compatibility with legacy wallet configs - add generation and persistence test coverage
- replace buyer Nostr pubkeys with Cashu wallet pubkeys in reclaim paths - ensure buyer Cashu pubkey is always included in refund keys - remove fallback to Nostr identity keys during escrow creation - default seller P2PK redeem key to Cashu wallet identity - fail safely when Cashu wallet identity is unavailable - update escrow documentation and tests - preserve compatibility with existing seller profile overrides
- add Cashu wallet identity guard for P2PK claims - unlock P2PK proofs through wallet.receive() - store and publish fresh spendable proofs after claim - pass privkey to safeSwap for P2PK redeem flows - remove legacy claim-signing TODO stub - add coverage for claim, redeem, guard, and regression paths
- introduce refund eligibility check based on locktime and refund keys - implement refund button in ClaimButton component - display success modal upon successful refund - enhance tests to cover refund scenarios and edge cases - ensure proper state management for refund process
…e proper execution flow
366f128 to
d696b7f
Compare
Addressed the 30406 recovery issue. I added a dedicated escrow-record restore flow during app startup (separate from wallet loading). It restores buyer escrow records from both the DB cache and relays, decrypts them, and rehydrates local escrow state before the orders dashboard loads. This allows reclaim data to survive:
Deduplication is handled through the existing orderId-based upsert path, and kind 30406 already uses a replaceable event keyed by the order d-tag. Added coverage for the restore path as well:
Current validation: 129 tests passing. |
|
@calvadev Addressed the feature-flag gating issue. The existing checkout flag is now used consistently across all P2PK UI surfaces:
This prevents users from enabling or seeing escrow features when checkout is blocked by policy. Added coverage for all three surfaces as well:
Validation:
|
|
@calvadev Confirmed this is intentional. The migration behavior is:
So there is a one-time write for users being migrated to WalletConfig V1, but it is not a recurring write on subsequent loads. Once the wallet identity exists, |
|
@calvadev Previously, if wallet config loading failed, I've changed the generation logic so a new identity is only created when wallet-config fetching succeeds and no existing wallet identity is found. If wallet-config loading fails, no replacement identity is generated or published. Instead, the wallet is marked unavailable and the user can retry once relay access is restored. Added coverage for:
Current validation: |
Description
This PR implements end-to-end P2PK escrow support using persistent Cashu wallet identities and completes the full escrow lifecycle from escrow creation through seller claim/redeem and buyer refund.
Wallet Identity & Configuration
17375wallet events.CashuWalletContextfor application-wide access.Escrow Ownership Migration
Seller Claim & Redeem Flows
wallet.receive(..., { privkey }).Buyer Refund Flow
Added refund support for expired P2PK escrow proofs.
Added refund eligibility checks using:
Added refund UI state and success handling.
Reused the same Cashu proof-unlocking path used for seller claims.
Ensured refunded proofs are converted into fresh spendable proofs before wallet storage.
Testing
Added and expanded coverage for:
Current test status:
Notes
Resolved or fixed issue
none
Screenshots (if applicable)
N/A (primarily protocol, wallet, and escrow flow changes)
Affirmation