BIP Implementation Notes
Companion to: yona:ruleset:v1.0 and the Base Interoperability Profile (BIP)
Document: Implementation Notes (non-normative)
Purpose: practical guidance for teams implementing BIP-conformant behavior. This page does not add, remove, or restate normative requirements; where there is any conflict, follow the YONA Ruleset, the BIP, and the BIP Conformance Test Suite.
License
Copyright © 2026 YONA LLC.
Text and explanatory content in this document are licensed under the Creative Commons Attribution 4.0 International License (CC BY 4.0).
License texts: CC BY 4.0
1. About This Page
1.1 Non-normative status
Unlike the BIP and the conformance suite, this page uses everyday language and recommendations (consider, typically, one approach). It is safe to treat the entire document as informative unless you are reading a direct quotation from another YONA document linked here.
1.2 Not an authoritative blueprint
No code structure, database schema, or operational policy on this page is required for conformance. Use what fits your stack, threat model, and release process; validate outcomes against the normative documents and your chosen test matrix.
2. How to Use the Document Set
2.1 Suggested reading order
- YONA Ruleset 1.0 — message payloads, fields, and ruleset semantics.
- Base Interoperability Profile (BIP) —
did:webdiscovery, required services, HTTPS + JOSE transport, endpoint behavior, conformance scope. - Reference Messages & DID Examples — end-to-end sequences, canonical JSON shapes, DID publication patterns, and a concise "drift" checklist.
- BIP Conformance Test Suite — what a harness is likely to assert, including invalid families, replay, and byte-exact hashing fixtures.
2.2 When to lean on the conformance suite
When your question is "is this HTTP status / body combination allowed?" or "must I reject this malformed field with a signed REJECT or with no YONA body?", answer it from the BIP and the suite's matrix, not from example code. The suite is deliberately precise about bindable vs unbindable failures, replay windows, and terminal responses.
3. Suggested Implementation Phases
Many teams reduce risk by separating concerns into layers that can be tested independently.
3.1 Phase A — Cryptography and messages
- Build, sign, and verify compact JWS for each
message_typeyou need. - Centralize payload construction so
ruleset_id, TTLs, and field names stay consistent. - Unit-test
request_jws_sha256against published byte-exact fixtures (Section 9).
3.2 Phase B — DID and HTTP surface
- Resolve counterparty
did:webdocuments; selectYonaPaymentIntentServiceandYonaAuthorizationServiceendpoints fromserviceentries. - Expose your own HTTPS handlers that accept
POSTwithContent-Type: application/joseand honorAccept: application/joseon the client side.
3.3 Phase C — Flows and state
- Implement pull-payment (retrieve intent → authorize with embedded intent) and/or push-payment paths.
- Add persistence and idempotency policies for
jti, intent rows, and repeatedyona.authorization_requesthandling (Section 7).
3.4 Phase D — Conformance and interop
- Run the matrix cases relevant to your claimed role (originator client, beneficiary server, or both).
- Capture evidence per your governance process (BIP discusses conformance evidence at a high level).
4. Cryptography and JWS Practice
4.1 Headers, payloads, and JSON
- Use Ed25519 with a protected header consistent with your DID document (
alg,typ, and akidthat resolves in the issuer DID document). - Remember the BIP rule: evaluate messages as received — avoid normalizing JSON (key reordering, pretty-printing) between verification and hashing steps.
- When generating payloads, pick one JSON serialization strategy (commonly stable key order or library default) and use it everywhere so signatures are reproducible in tests.
4.2 request_jws_sha256
The response binds to the exact authorization request compact JWS string (ASCII bytes), not to a canonicalized parse tree. Hash the raw request body your verifier used, then base64url-encode the SHA-256 digest. Mix-ups here are a frequent interop breaker; the conformance suite includes dedicated coverage.
4.3 Duplicate JSON members and parsing
Duplicate object keys are invalid. If your JSON parser silently picks a winner, you may pass local tests yet fail conformance. Prefer a parser that rejects duplicates, or add a raw-content check as required by the BIP.
5. DID Resolution and Service Discovery
5.1 Caching and rollout
Production systems usually cache DID documents for a few minutes to balance load and freshness. Plan key rotation with an overlap window (see the key-rotation pattern in Reference Messages Section 4.7).
Local development with did:web often uses HTTP for localhost; production endpoints should follow the BIP HTTPS requirements.
5.2 Verifying the signing key (kid)
A robust verifier loads the issuer DID document, checks that the JWS kid refers to a verification method authorized for assertion (per your ruleset/DID profile), imports the public JWK, then verifies the compact JWS. Skipping the authorization graph and trusting only the bare key document opens avoidable ambiguity during key rotation.
6. Flow-Specific Guidance
6.1 Pull-payment
- Treat
yona.retrieve_intentas a keyed lookup: the locator is not a substitute for the signedyona.payment_intent. - After retrieval succeeds, the originator builds a pull-style
yona.authorization_requestthat embeds the exact beneficiary-signed payment intent JWS. - A retrieval failure is not an authorization decision; do not map it to
ACCEPT,REJECT, orNO_RESPONSEsemantics (see BIP Section 5.1).
6.2 Push-payment
- Push requests carry
beneficiary_handle,payment_terms, andintended_asset_type; there is noyona.payment_intentretrieval step. - Keep the handle opaque at the originator: it is a beneficiary-local reference, not a general-purpose payment URI.
7. State, Idempotency, and Replay
7.1 jti and repeated requests
The ruleset and suite use jti freshness and repeated-request semantics to block replays and to define how retries behave. Decide where your system records jti (authorization service, payment-intent service, or both) and how long entries live relative to message exp.
For yona.authorization_request, many implementations also need a policy for "same intent_id, new network retry" versus "duplicate with changed material" — the conformance suite encodes expectations you should mirror rather than inventing ad hoc rules.
7.2 Binding embedded pull intents
For pull-payment, compare the embedded yona.payment_intent to what your beneficiary system considers authoritative (amount, currency, acceptable assets, locator). If a client replays an authorization with different embedded material for the same stored intent, treat that as a policy violation, not a silent success.
8. HTTP Status Codes Versus YONA Bodies
A recurring implementation gap is assuming every error returns JSON or every denial returns HTTP 4xx. Under BIP, YONA terminal messages are HTTP 200 + application/jose bodies; some failure modes explicitly require no YONA response body.
8.1 Authorization endpoint
When the beneficiary can construct a bound terminal response (including deterministic validation failures), the BIP expects a signed yona.authorization_response with ACCEPT or REJECT. When binding inputs are missing or the body is unparseable in ways the profile forbids, the server must not emit a YONA message (see BIP Section 5.2).
8.2 Payment-intent retrieval
The payment-intent endpoint never returns yona.authorization_response. If you cannot return a verified yona.payment_intent, return a non-YONA HTTP outcome; clients must treat that as retrieval failure, not authorization.
9. Testing Workflow
9.1 Fixtures and golden vectors
Start from the suite's published fixtures for request_jws_sha256 and wrong-binding cases. Add your own golden tests for message builders so refactors do not silently change byte sequences.
9.2 Roles under test
Clarify whether you are implementing the originator client, the beneficiary server, or both. The suite names roles explicitly; half-port implementations often pass local mocks yet fail cross-VASP interop because only one side was exercised.
10. Interoperability Checklist
ruleset_idis exactlyyona:ruleset:v1.0everywhere.- DID service types are spelled
YonaPaymentIntentServiceandYonaAuthorizationService. - Pull uses
acceptable_asset_types; push usesintended_asset_type. beneficiary_handlematches the normativedid=…;alias=…pattern.request_jws_sha256is computed from the exact compact JWS bytes you received.- Your HTTP client sends
Accept: application/joseon YONA calls. - Optional DID services (travel rule, settlement, assurance) never change core authorization semantics.
11. Pitfalls and Field Drift
The Reference Messages document ends with a focused list of common drift points (hashing, retrieval vs authorization, mixed invalid cases, handle form, field names, optional services). Start there when debugging a counterparty mismatch:
Reference Messages — §6.1 Common drift points
11.1 Related notes in Reference Messages
Also read §6.2–§6.4 for pull vs push reminders and optional service boundaries — they are short and align tightly with BIP intent.