Designing Standalone Escrows in Pontmore PIP-01

Designing Standalone Escrows that Expands Pontmore Protocol’s PIP-01

At the moment PIP-01(Escrow descriptor) of the pontmore Protocol serves a narrow albeit crusial purpose; it allows agents to discover compatible escrow mechanisms for fiat-to-Bitcoin and vice versa swaps dictated by the PIP-02 state machine.It is just a discovery tool not an execution engine.

But as the network evolves, the need for programmable, trust-minimized agreements extends far beyond simple swaps.Whether it’s milestone-based freelance contracts, multi-party wagers or decentralized arbitration, developers need a way to instantiate and operate escrows without relying on out-of-band negotiation.

Issue [#11] is the driving force leading to the proposed expansion of PIP-01,by introducing an optional service block [#PR12], this upgrades an escrow from discovery only to a fully autonomous standalone service interface

Below are design choices ,inherent trades-off and risks of operating a standalone pontmore Escrow that advertises the service block:

1. Core Design Choices: The service Interface

To make an escrow usable as a standalone service, a client must know exactly how to talk to it, how to authenticate, and what state transitions are acceptable.

The schema_url vs. Event Bloat
A major design decision was how to specify the API contract without bloating the Nostr event. The solution is the schema_url. Rather than embedding HTTP paths and payload structures directly into the descriptor, the descriptor points to a normative, machine-readable schema (i.e OpenAPI spec in this case). This keeps the PIP-01 event lightweight for Nostr relays while providing a strict, versioned wire contract for applications to consume.

NIP-98 Authentication

To maintain Nostr-native identity, the proposal recommends nostr_http_auth (NIP-98) for HTTPS transports. This ensures that the participant’s Nostr pubkey remains their identity. It explicitly forbids the requirement of published bearer secrets for public protocol operations, keeping the public/private data boundary intact.

split_decision and Generic Release Vocabularies

Swap escrows are usually binary: either the buyer gets the Bitcoin, or the seller gets refunded. Standalone escrows require more nuance. The PR introduces split_decision, allowing an arbiter (or mutual consent) to allocate funds across participants in declared proportions. Furthermore, release conditions are abstracted into generic formats like oracle_signature and application_signed_result, decoupling the escrow from swap-specific logic.

2. Escrow State Machines and Deadlock Prevention

A standalone escrow is fundamentally a state machine. The PR explicitly defines canonical states (created, partially_funded, active, release_pending, and terminal states) to remove cross-operator ambiguity and enhance interoperability

More importantly, the design tackles two massive vectors for griefing and locked funds:

  • Partial-Funding Griefing: In a two_party or m_of_n model, one participant could fund their side while the other abandons the protocol, locking the first user’s capital indefinitely. The PR mandates a funding_timeout. If the threshold isn’t met, a cancel operation MUST refund any already-funded participants. The operator cannot treat a partially funded state as implicit consent to release.

  • Refund-Trigger Fallbacks: If a timeout requires mutual_consent, a dispute between stubborn parties creates an infinite deadlock. The new spec dictates that any refund_trigger relying on mutual consent MUST declare an alternative fallback resolution (like operator_decision or oracle_signature) to guarantee the escrow can reach a terminal state.

3. The Canonical Subtypes: Trade-offs & Security Risks

The protocol defines three canonical escrow subtypes. When operating them in a standalone context, applications must weigh distinct security assumptions and operational risks.

Subtype Best For Primary Risk Trust Assumption
lightning_hold_invoice Rapid, near-instant conditional payments. Routing-node liquidity penalties. Network routing stability.
custodial_escrow Network-agnostic, complex logic, splits. Full counterparty risk. Operator honesty.
cashu_escrow Bearer-instrument custody, non-relational balances. Mint liveness & reserve failure. Mint solvency & uptime.

The lightning_hold_invoice Dilemma

Lightning hold invoices are excellent for trust-minimized, instant swaps. However, they are fundamentally hostile to long-running standalone escrows.

  • The Risk: A hold invoice locks liquidity across every intermediate node in the routing path. If an escrow (like a freelance contract) takes days to resolve, routing nodes will likely force-close channels to reclaim their capital.

  • The Takeaway: Applications should strictly avoid this subtype for anything other than short-lived, synchronous transactions.

The custodial_escrow Reality

This subtype is the most flexible and network-agnostic, but it carries the heaviest trust burden.

  • The Risk: The operator is declared as the custody, release, and refund authority. Cryptographically, this is indistinguishable from a centralized database. The protocol standardizes the API, but it cannot prevent the operator from absconding with the funds.

  • The Takeaway: Selection of this descriptor is purely a trust decision. Applications must rely on off-protocol reputation, or operators must begin utilizing externally verifiable proofs of reserve or collateral.

The cashu_escrow Dependency

Cashu introduces a fascinating model where the custody is bound to the bearer instrument (the ecash token) via NUT-11 P2PK timelocks, rather than a relational database entry held by the operator.

  • The Risk: The escrow is entirely dependent on the declared mint_url. If the mint goes offline or its reserves fail before the locktime expires, the tokens are unredeemable. Your refund pubkey is useless if the mint backing it no longer exists.

  • The Takeaway: Mint liveness is an implementation assumption outside of Pontmore’s protocol state. Clients must treat the mint as an additional trusted party and refuse descriptors tied to unvetted mints.

The Application-as-Oracle Risk

When an escrow uses application_signed_result as a release trigger, the originating application becomes an oracle. If that application’s signing backend is compromised, an attacker can mint valid signatures and drain any active escrows relying on it. To mitigate this, the PR mandates strict replay protection—binding signatures to specific escrow identifiers and result hashes—and encourages pairing application signatures with threshold participant signatures for high-value contracts.

Conclusion

By extending PIP-01 with the service interface, Pontmore is laying the groundwork for a rich ecosystem of decentralized, verifiable agreements. However, programmable money requires programmable responsibility.

The proposed changes force operators to explicitly declare their execution assumptions, timeouts, and fallback policies, while standardizing the interface so developers can build freely. By understanding the infrastructure realities of Lightning, Custodial, and Cashu subtypes, developers can select the right security model for their specific application needs.

1 Like

This is great work, @denver , the work you’ve described above has pushed forward viability of standalone, service-invocable escrows in Pontmore.

When reviewing this design of standalone escrow flows, it occurred to me we need to clarify an important protocol boundary: PIP-01 should make escrow services discoverable and interoperable, but it should not try to define every service operation, release decision format, internal state, or subtype-specific implementation detail directly inside the descriptor.

1 Like

I have opened a cleanup PR for PIP-01, the Pontmore escrow descriptor specification.

The motivation is simple: PIP-01 had started to carry too many responsibilities. It was no longer just describing escrow compatibility metadata; it was also defining service invocation fields, funding model vocabulary, release decision formats, subtype-specific field lists, and operational behavior that belongs in service schemas or swap lifecycle specs.

This simplification moves PIP-01 back toward a smaller, clearer role:

  • describe public escrow compatibility metadata
  • expose supported networks and funding cardinality
  • point to a service schema when direct service use is available
  • keep service behavior in OpenAPI/AsyncAPI
  • keep swap lifecycle behavior in PIP-02
  • keep dispute and timeout policy in PIP-03

The main changes include making service.schema the only service-related descriptor field, replacing named funding models with a simple m of n funding rule, removing descriptor-level release_rules, and trimming subtype sections so they only describe purpose, compatibility invariants, and public/private boundaries.

The goal is to make Pontmore escrow descriptors easier to implement, review, and extend without forcing every operator or application into the same internal service model.

Here are the references

1 Like

see the impact assessment on existing public escrows : Simplify PIP-01 escrow descriptor by okjodom · Pull Request #17 · pontmore/protocol · GitHub

1 Like

I’m currently updating the POC escrow and its client to match the current Discriptor specs .I’ve also written an article on pontmore standalone Escrows