Prompt: set up ird p2p infrastructure for a WebRTC / libp2p app
Have an agent create a p2p app on ird — WebSocket signaling, STUN/TURN,
a libp2p circuit relay and an optional offline mailbox at
<name>.ap2p.ro or your own domain — lock it to your site's origins,
test it end to end, and hand your codebase the exact client config.
Needs: ird access (MCP server or the ird CLI, logged in); optionally a hostname on a zone hosted on ird DNS for a custom domain
Costs: hourly per app plus per MB relayed through TURN or the libp2p relay and per MiB-hour of mailbox storage (credits_prices → recurring.p2p-app-hourly); signaling traffic is currently free
Group: p2p
Paste everything below the line into a fresh conversation. Fill in the
FILL IN block first.
Task
Provision p2p infrastructure for the app described below and produce a
config block I can paste into the client.
FILL IN
NAME: whiteboard # lowercase letters, digits, hyphens → whiteboard.ap2p.ro
ORIGINS: https://board.example.ro, *.example.ro # sites allowed to use it (blank = any origin — dev only)
STACK: plain WebRTC # plain WebRTC | y-webrtc | trystero | peerjs | js-libp2p/Helia/OrbitDB
DOMAIN: rtc.example.ro # custom hostname on an ird-DNS zone, or blank
MAILBOX: no # yes if peers must catch up when never online together
LIMITS: defaults # or knobs to change, e.g. max_room_peers=32
Non-negotiable rules
- Cost first. Show the hourly app price × 730 plus the per-MB relay
rate before creating; wait for a yes.
- Origins are a full replacement.
p2p_set_origins replaces the
whole list — always read the current list and send it complete. An
empty list means any origin: fine for local development, say so if
it stays that way.
- Read the protocol before writing client code.
p2p_protocol
returns the full wire contract (frames, TURN credential format, relay
multiaddrs, mailbox API). Don't guess it.
- Disabling the mailbox drops its stored messages. Only on my say.
Steps
A. Create. p2p_list_apps — reuse NAME if it exists. Otherwise
p2p_create_app(name=NAME, origins=[ORIGINS]) (CLI:
ird p2p create NAME --origin … --origin …). Keep: signaling_url,
turn_credentials_url, ice_urls, relay_multiaddrs / relay_peer_id
(appears once the node reports it — re-read p2p_list_apps). Wildcards
are bare patterns (*.example.ro), never https://*.example.ro.
B. Custom domain. If DOMAIN: p2p_domain_add(app=NAME,
hostname=DOMAIN) (CLI: ird p2p domains add NAME DOMAIN). On an
ird-hosted zone the record and certificate are automatic; otherwise set
the returned dns_cname_target as a CNAME and call p2p_domain_verify.
Then signaling and /turn-credentials also serve at https://DOMAIN.
C. Mailbox. If MAILBOX: p2p_set_mailbox(app=NAME, enabled=true,
open_mint=true) (CLI: ird p2p mailbox NAME --enable). open_mint=false
if only my backend should mint tokens (Node/Go peers always mint through
the API anyway).
D. Limits. If LIMITS ≠ defaults: p2p_set_limits(app=NAME, …) — only
the keys passed change; 0 resets a key to its default. Show the resulting
settings from p2p_list_apps.
E. Test end to end.
GET https://<hostname>/.well-known/ap2p → JSON descriptor with the
endpoints and enabled features (relay, mailbox).
p2p_turn_credentials(app=NAME, ttl_sec=600) (CLI: ird p2p creds NAME)
→ a username/credential pair; confirm ice_urls include turn: and
turns: entries. (Each mint costs a tiny fee; browsers fetch their
own from turn_credentials_url.)
- Open a WebSocket to
signaling_url, send a join for a test room,
expect the peers frame (exact frames per p2p_protocol). From a
shell: websocat or a 10-line Node script with ws.
- If MAILBOX:
p2p_mailbox_send(app, room="test", data="hi") then
p2p_mailbox_recv(app, room="test") returns it.
- If STACK is libp2p: dial one of
relay_multiaddrs from a js-libp2p
node and reserve a slot (recipe in p2p_protocol).
F. Client config. Produce, for STACK:
- plain WebRTC: an
iceServers builder that fetches
turn_credentials_url (same-origin-checked, so from an allowed
ORIGIN) and merges ice_urls; the signaling_url and the join frame.
- y-webrtc:
signaling: ['wss://<hostname>/y-webrtc'].
- trystero: the
/tracker endpoint; peerjs: new Peer({ host: '<hostname>', port: 443, secure: true }) (default path).
- js-libp2p/Helia/OrbitDB:
relay_multiaddrs for the listen address
(/p2p-circuit) and pubsub peer discovery, per p2p_protocol.
Note that compat endpoints (/y-webrtc, /tracker, /peerjs) exist on
the same hostname with no rewrite.
G. Cost recap. p2p_usage → current hourly/monthly and relayed bytes.
Deliverable
The app's hostnames, signaling_url, turn_credentials_url, ice_urls,
relay_multiaddrs, mailbox_url (if on), the origin allowlist, the
config block for STACK, test results per step E, and the delete command
(ird p2p delete NAME) for later.