Introducing Pontmore: a Nostr-native protocol for agent discovery, escrow, and swaps

Hi Open Bitcoin Africa community,

I would like to introduce Pontmore, a Nostr-native protocol family for agent identity, capability discovery, escrow declaration, and swap lifecycle coordination.

Pontmore is designed for a world where services, market makers, operators, and automated participants can publish what they do publicly, discover each other through Nostr, and coordinate swaps without making a single application account the root of identity.

The core idea is simple:

An Agent is a protocol participant that publishes capabilities and can conduct swaps. A Swap is the exchange from fiat to Bitcoin, or Bitcoin to fiat. A Nostr pubkey is the root agent identity, allowing for portability of agents in an open network.

Pontmore does not require the Agent to be a human

It’s easiest to think of an Agent here as the very familiar “Mobile Money Agents”. Such human agents are key participants how money move in the global south through networks like M-Pesa, MTN MoMo, Airtel Money, bKash and GCash.

Applications, dashboards, indexes, compliance tools, and operator systems can wrap that identity, but the public protocol surface remains portable and verifiable.

Protocol Definitions

Pontmore currently defines four required protocol documents:

Defines how an Agent publishes its public profile, supported capabilities, payment channels, regions, limits, pricing policy references, and default escrow descriptor.

Defines how escrow mechanisms are declared publicly, including supported networks such as Bitcoin or Lightning, funding rules, release rules, refund rules, and dispute assumptions.

Defines the event lifecycle for swaps: request, transitions, evidence, disputes, notes, and snapshots. The swap history is append-only, while private data can move through encrypted Nostr messages.

Defines dispute classes, timeout classes, evidence boundaries, and resolution modes. The swap state machine is public, but sensitive evidence stays private by default.

## Why this matters

Many Bitcoin services today depend on platform-specific accounts, internal databases, and private trust assumptions. That can work inside one app, but it makes interoperability difficult.

Pontmore tries to separate public protocol facts from private operator systems.

Public protocol facts include:

  • who an Agent is

  • what capabilities they publish

  • which escrow model they reference

  • what swap was requested

  • how the public lifecycle advanced

  • whether a dispute was opened or resolved

Private operator data can still exist, but it does not become the canonical protocol state.

That means different clients, indexes, operators, and automation systems can coordinate around the same public event model while keeping sensitive details out of the public feed.

Possible Use Cases

Pontmore can support:

  • peer-to-peer Bitcoin and fiat swaps

  • Lightning-based escrow flows

  • agent discovery for local liquidity providers

  • public capability directories

  • interoperable swap clients

  • escrow operators that publish their rules clearly

  • dispute-aware swap coordination

  • regional Bitcoin markets where multiple frontends can discover the same agents

  • automation that helps coordinate swaps without owning user identity

For example, an Agent could publish that it supports Kenyan shilling swaps, Lightning settlement, specific payment channels, certain limits, and a particular escrow descriptor. A client can discover that Agent over Nostr, start a swap, track public state transitions, and keep sensitive payment details in encrypted messages.

Privacy Model

Pontmore does not assume that everything belongs on the public timeline.

The public state machine records the minimum shared facts needed for coordination and auditability. Sensitive payloads such as invoices, bank details, payout instructions, screenshots, internal notes, and private documents should stay in encrypted/private channels unless a dispute policy requires limited disclosure.

The goal is interoperability without unnecessary exposure.

Current Status

Pontmore is still in draft form.

The current repository contains only the minimum interoperable core PIPs, so the protocol remains small and reviewable.

The core repository is open source:

With a proof of concept hosted at:

This draft has been adopted by Minmo - the proposer[1][2].

How to Contribute

The most useful contributions right now are:

  • protocol-focused review

  • proof of concept implementations

  • general protocol discussion

  • feedback on whether the event model is clear enough for independent implementations

  • challenges to unclear terminology or missing protocol rules

  • suggestions for better boundaries between public protocol state and private operator data

  • concrete improvements as issues or pull requests

The repository is intentionally focused on protocol text.

Application UX, database schemas, deployment details, and SDK plans should live elsewhere unless they are needed to clarify the protocol itself. You can [read the source code]( GitHub - pontmore/nextjs-poc · GitHub ) for the publicly hosted proof of concept app.

Feedback from builders working on Bitcoin, Lightning, Nostr, escrow, and local liquidity markets would be especially valuable.


  1. Minmo implements the Pontmore Protocol, and is one of many possible operator in the resulting network of Pontmore Agents. As an operator, Minmo provides tools which help in operating a subset of the emergent Open network of Agents compatible with the specifications defined in this protocol. It does not and will not have unilateral ownership of Agents in the network. Generally, no single operator should be able to delete, censor, or prevent Agents from participating in the network proposed. ↩︎

  2. Minmo proposes the original shape of Pontmore Protocol, and commits to working collaboratively in the open with other individual or organizational contributors who want to further the ideas proposed. ↩︎

1 Like

Hi everyone,

I’ve been working on a way for Pontmore escrows to advertise their full service capabilities directly on Nostr. The goal here is simple: anyone building an app should be able to just discover, parse, and invoke a published escrow service without needing out-of-band coordination.

Right now, PIP-01 is great for discovery and matching within standard swap flows. But if you want to build a standalone, non-swap application (like a two-party dice game) using a Pontmore escrow, the current descriptor doesn’t tell your app how to actually talk to the service. It’s missing the API endpoints, the auth model, and the expected payload formats.
To fix this Issue #11, I’ve opened PR #12

The PR extends PIP-01 with an optional service block. This allows an escrow to publicly advertise its HTTPS endpoints, require Nostr-native NIP-98 authentication, and specify exactly which operations and release-decision formats it supports—all without leaking the operator’s private custody or routing details.

1 Like

To prove this actually works in practice, I’ve built out two working repositories:

1. The Escrow Backend: pontmore-lightning-escrow

A standalone, PIP-01 conformant custodial escrow service over HTTPS.

  • Uses Blink for Lightning custody and Supabase (Postgres RPCs) for atomic state transitions.
  • Implements the six canonical operations proposed in the PR (create, funding_instructions, fund_status, release, refund, cancel).
  • Fully relies on NIP-98 HTTP Auth—every mutating request requires a signed kind 27235 event, meaning the Nostr pubkey is the participant identity.

2. The Validation Toolkit: descriptor-POC

A Rust workspace to parse, validate, and test these new standalone descriptors.

  • Core Library: Parses the JSON against PIP-01 rules, classifies if it is DiscoveryOnly or StandaloneSufficient, and verifies the wrapping Nostr event signatures.
  • Tooling: Includes a CLI to quickly validate local descriptor files, and a lightweight axum mock web server to simulate the escrow service for frontend testing.

I’d love for builders here to tear into the PR and the code and share there findings/feedback.

1 Like

This is really cool. I listed the proof of concepts under pontmore.xyz projects

I am working on an a simple dice-roller app which can just connect to advertised pontmore escrows and carry out it’s functions. The idea is to test the escrow invocation spec proposed by Define escrow service invocation by mk-Denver · Pull Request #12 · pontmore/protocol · GitHub

I appriciate the idea of building a a simple dice-roller client to test the proposed idea ,feedback on your findings will be highly appriciated

Quick update:
I’ve Just pushed some additional implementations to PR(#12). This update patches several structural loopholes and standalone limitations identified in PIP-01, with a minor alignment in PIP-03.

Key Updates (PIP-01):

  • Security Fixes: Patched the Sybil-join loophole (enrollment tokens are now strictly bound to the joining participant’s pubkey) and cross-instance replay attacks (oracle/threshold signatures MUST now commit to the stable escrow ID).
  • State Machine & Lifecycle: Added strict state transition rules (created through to terminal states) to fix ambiguous states. Resolved the “funding limbo” by adding a funding_timeout that mandates full refunds for partially funded sides.
  • Disputes & Deadlocks: Introduced the split operation and split_decision format for proportional payouts. Fixed the mutual-consent deadlock by requiring a non-consent refund_trigger fallback (this is also minimally mirrored in PIP-03 to ensure operators resolve timeouts).
  • Risk Documentation: Added a new section detailing standalone implementation risks, specifically addressing Lightning routing-node penalties, custodial counterparty risks, and Cashu mint liveness.
1 Like

I was wondering if we need state machine declarations for the escrows. A strict state machine declaration would mean the protocol has an opinion on the internal implementation of the escrow.

Question: Is escrow variant and public interface definition declared via descriptor mechanism sufficient for interoperable pontmore escrows, or does the protocol also need to define the escrow implementation details to a degree ?

The public interface definition declared via descriptor mechanism is only sufficient for an escrow to be standalone, but for it to be an interoperable pontmore escrows, the the protocol will need to define the implementation details to a degree ,example; the escrow instance state machine,of which in this case are public states