feat(funding): explicit crypto-vs-fiat classification — paymentType + paymentRail knownValues#232
feat(funding): explicit crypto-vs-fiat classification — paymentType + paymentRail knownValues#232s-adamantine wants to merge 1 commit into
Conversation
Add an explicit crypto-vs-fiat discriminator to org.hypercerts.funding.receipt: - New optional paymentType string, knownValues [crypto, fiat]. The amount/currency pair cannot express this (receipts often record normalized fiat-equivalent amounts for crypto payments; stablecoins carry fiat-pegged currencies), so the asset class needs an explicit field. Absent/unrecognized values classify as unclassified, not fiat. - paymentType is orthogonal to paymentRail (mechanism): a card-funded crypto purchase is paymentType 'crypto' + paymentRail 'credit_card'. - paymentRail gains knownValues [onchain, payment_processor, bank_transfer, credit_card, cash, check] (previously prose-only examples) so form UIs can offer a canonical vocabulary instead of free text. - paymentNetwork description distinguishes chain (onchain) vs processor/scheme (fiat) uses and strongly recommends it for onchain payments (a tx hash is uninterpretable without its chain). Non-breaking: new field optional; knownValues advisory; existing receipts remain valid.
🦋 Changeset detectedLatest commit: 9eeae49 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📝 WalkthroughWalkthroughAdds an optional ChangesFunding receipt paymentType discriminator
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5 | ❌ 2❌ Failed checks (2 inconclusive)
✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.changeset/funding-receipt-payment-type.md:
- Line 11: Update the `paymentRail` changelog note to keep the wording advisory
rather than implying a closed set of allowed values. In
`.changeset/funding-receipt-payment-type.md`, revise the sentence around
`knownValues` so it says the listed rails provide a canonical vocabulary or
examples, while still allowing custom rail values; avoid language like “instead
of free-text input” that suggests consumers should reject unlisted rails.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 3a230b5c-9d96-44e7-bae6-8e8946a08f34
📒 Files selected for processing (3)
.changeset/funding-receipt-payment-type.mdSCHEMAS.mdlexicons/org/hypercerts/funding/receipt.json
|
|
||
| - New `paymentType` string with `knownValues: ["crypto", "fiat"]` — the explicit asset-class discriminator. Consumers classify by this field and treat receipts without it (or with an unrecognized value) as unclassified, never silently as fiat. The `amount`/`currency` pair cannot substitute: receipts often record normalized fiat-equivalent amounts for crypto payments, and stablecoins carry fiat-pegged currencies. | ||
| - `paymentType` is orthogonal to `paymentRail` (the transfer mechanism): a card-funded crypto purchase is `paymentType: "crypto"` + `paymentRail: "credit_card"`. | ||
| - `paymentRail` now declares `knownValues: ["onchain", "payment_processor", "bank_transfer", "credit_card", "cash", "check"]` (previously prose-only examples), giving form UIs a canonical vocabulary instead of free-text input. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Keep paymentRail wording advisory.
The lexicon still permits custom rail values, so this should not read as “instead of free-text input.” That phrasing can push consumers to reject valid non-listed rails.
Suggested wording
- `paymentRail` now declares `knownValues: ["onchain", "payment_processor", "bank_transfer", "credit_card", "cash", "check"]` (previously prose-only examples), giving form UIs a canonical vocabulary instead of free-text input.
+ `paymentRail` now declares `knownValues: ["onchain", "payment_processor", "bank_transfer", "credit_card", "cash", "check"]` (previously prose-only examples), giving form UIs a recommended vocabulary while still allowing custom values.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `paymentRail` now declares `knownValues: ["onchain", "payment_processor", "bank_transfer", "credit_card", "cash", "check"]` (previously prose-only examples), giving form UIs a canonical vocabulary instead of free-text input. | |
| `paymentRail` now declares `knownValues: ["onchain", "payment_processor", "bank_transfer", "credit_card", "cash", "check"]` (previously prose-only examples), giving form UIs a recommended vocabulary while still allowing custom values. |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.changeset/funding-receipt-payment-type.md at line 11, Update the
`paymentRail` changelog note to keep the wording advisory rather than implying a
closed set of allowed values. In `.changeset/funding-receipt-payment-type.md`,
revise the sentence around `knownValues` so it says the listed rails provide a
canonical vocabulary or examples, while still allowing custom rail values; avoid
language like “instead of free-text input” that suggests consumers should reject
unlisted rails.
What
Adds an explicit crypto-vs-fiat discriminator to
org.hypercerts.funding.receipt:paymentTypestring,knownValues: ["crypto", "fiat"]— the asset-class discriminator. Absent/unrecognized ⇒ unclassified (never silently fiat).paymentRailgainsknownValues["onchain", "payment_processor", "bank_transfer", "credit_card", "cash", "check"]— previously these existed only as prose examples, and e.g. certified.app's record-payment form is free-text, so ecosystem rail values were destined to diverge.paymentNetworkdescription now distinguishes its two uses — the chain foronchainpayments (strongly recommended: a tx hash is uninterpretable without its chain) vs the processor/scheme for fiat rails.Non-breaking: new field optional,
knownValuesadvisory. Changeset:minor.Why
Ma Earth is publishing platform-authored funding receipts for donations across both fiat (Stripe/PayPal) and crypto (on-chain) rails — first records are live on the dev Certified network (receipts, each carrying a remote
app.certified.signature.proofplatform attestation). Consumers need to split crypto from fiat deterministically, and nothing on the current record can express it:currencycan't: platforms commonly record a normalized fiat-equivalent (amount: "100.00", currency: "USD") for an on-chain donation, and stablecoin payments carry fiat-pegged currencies either way.paymentNetworkcan't: optional, and classifying via it needs a maintained which-networks-are-chains registry in every consumer.paymentRailcan't: every consumer invents its own heuristic over uncontrolled vocabulary.Design discussion — input wanted
We considered three shapes; this PR implements A. Happy to switch if reviewers prefer otherwise — now is the cheap moment to settle this: a scan of all three PDSes found only 5
funding.receiptrecords network-wide, 4 of them our own dev demo data and the 5th with nopaymentRailat all, so there is no migration burden yet.paymentType: crypto|fiat;paymentRailstays pure mechanismtype: crypto,rail: credit_card); mild redundancy for the common casepaymentRail === "onchain"paymentRail: "crypto"as a flat enum value alongside mechanisms (Stripe'spayment_method.typeprecedent)Arguments for A: a foundational lexicon should state the classification rather than have every consumer derive it; the two axes (what asset / how moved) are genuinely orthogonal; and the classification rule for consumers becomes a field read instead of a convention.
Related
Companion PR from the same integration solving the remaining modelling gaps (FX stamping, refund representation,
transactionIdprivacy guidance): #233. The two are independent and can land in either order.Checks
npm run checkgreen (validate + gen + typecheck + build + 182 tests)SCHEMAS.mdregenerated; changeset includedSummary by CodeRabbit