From b6ae142e3ca66f8d16e599065f794782d400c8ec Mon Sep 17 00:00:00 2001 From: Kristofer Date: Fri, 30 Oct 2026 15:36:16 +0100 Subject: [PATCH] api: validate against @hypercerts-org/lexicon 1.6.0 Bump the pinned lexicon package from 1.5.0 to 1.6.0 and refresh the explorer snapshots and the hypercerts-api skill's OpenAPI descriptions. 1.6.0 only adds optional fields (langs, createdVia) and makes funding receipt amount and currency optional, so no record that validated before is rejected. TECH-822 --- .../hypercerts-api/references/openapi.json | 4 +- .changeset/lexicon-1-6-0.md | 5 ++ docs/coverage.json | 2 +- docs/openapi.json | 6 +- docs/sources/index.json | 2 +- .../app.certified.actor.organization.json | 9 +++ .../lexicons/app.certified.actor.profile.json | 9 +++ .../app.certified.signature.defs.json | 26 ++++++++- .../org.hypercerts.claim.activity.json | 9 +++ .../lexicons/org.hypercerts.collection.json | 9 +++ .../org.hypercerts.context.attachment.json | 19 ++++++- .../org.hypercerts.entity.feature.json | 9 +++ .../org.hypercerts.funding.receipt.json | 57 +++++++++++++++---- happyview-modules/package.json | 2 +- pnpm-lock.yaml | 10 ++-- 15 files changed, 150 insertions(+), 28 deletions(-) create mode 100644 .changeset/lexicon-1-6-0.md diff --git a/.agents/skills/hypercerts-api/references/openapi.json b/.agents/skills/hypercerts-api/references/openapi.json index 3655942..7439a71 100644 --- a/.agents/skills/hypercerts-api/references/openapi.json +++ b/.agents/skills/hypercerts-api/references/openapi.json @@ -187,7 +187,7 @@ "org.hypercerts.context.acknowledgement.main": {"type":"record","description":"Acknowledges a record (subject) or its relationship in a context. Created in the acknowledging actor's repo to form a bidirectional link. Examples: a contributor acknowledging inclusion in an activity, an activity owner acknowledging inclusion in a collection, or a record owner acknowledging an evaluation."}, "org.hypercerts.api.defs.acknowledgementView": {"type":"object","description":"Acknowledgement record with its publisher actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.context.acknowledgement.main"}}}, "org.hypercerts.context.getAcknowledgement.output": {"type":"object","required":["acknowledgement"],"properties":{"acknowledgement":{"$ref":"#/components/schemas/org.hypercerts.api.defs.acknowledgementView"}}}, - "org.hypercerts.context.attachment.main": {"type":"record","description":"An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation)."}, + "org.hypercerts.context.attachment.main": {"type":"record","description":"An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation) or related to an account profile."}, "org.hypercerts.context.getAttachment.attachmentView": {"type":"object","description":"Attachment with its hydrated publisher and unchanged source record; subject, content, and location references are not expanded, and external files are not fetched. Missing publisher sidecars are null; query or hydration failures fail the request.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.context.attachment.main"}}}, "org.hypercerts.context.getAttachment.output": {"type":"object","required":["attachment"],"properties":{"attachment":{"$ref":"#/components/schemas/org.hypercerts.context.getAttachment.attachmentView"}}}, "org.hypercerts.context.evaluation.main": {"type":"record","description":"An evaluation of a hypercert record (e.g. an activity and its impact)."}, @@ -205,7 +205,7 @@ "org.hypercerts.entity.defs.featureView": {"type":"object","description":"Indexed feature record with its hydrated author actor.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.entity.feature.main"}}}, "org.hypercerts.entity.getFeature.output": {"type":"object","required":["feature"],"properties":{"feature":{"$ref":"#/components/schemas/org.hypercerts.entity.defs.featureView"}}}, "org.hypercerts.entity.listFeatures.output": {"type":"object","required":["features"],"properties":{"features":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.entity.defs.featureView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, - "org.hypercerts.funding.receipt.main": {"type":"record","description":"Records a funding receipt for a payment from one user to another user. It may be recorded by the recipient, by the sender, or by a third party. The sender may remain anonymous."}, + "org.hypercerts.funding.receipt.main": {"type":"record","description":"Records a payment from a sender to a recipient. Any party may record it, and the sender may stay anonymous. When the sender chose the recipient, record one receipt to the final recipient even if platforms or hosts passed the funds on. When an intermediary chose (regranting), record the payment into it and each onward payment as separate receipts. A receipt may be updated in place under the same record key: its URI does not change, so references by URI keep resolving, but a strongRef (as likes and reposts use) still pins the earlier CID, and signatures bind to content and must be renewed. An earlier version cannot be recalled from readers that kept it."}, "org.hypercerts.funding.getReceipt.receiptView": {"type":"object","description":"Funding receipt with its publisher actor hydrated; the indexed record is unchanged, including its decimal-string amount, and party and funded-target references are not expanded. Missing publisher profile or organization sidecars are null; indexedAt is null when the index has no timestamp. A receipt is not proof of payment.","required":["uri","cid","indexedAt","did","author","record"],"properties":{"uri":{"type":"string","format":"at-uri"},"cid":{"type":"string","format":"cid"},"indexedAt":{"anyOf":[{"type":"string","format":"datetime"},{"type":"null"}]},"did":{"type":"string","format":"did"},"author":{"$ref":"#/components/schemas/org.hypercerts.api.defs.actorView"},"record":{"$ref":"#/components/schemas/org.hypercerts.funding.receipt.main"}}}, "org.hypercerts.funding.getReceipt.output": {"type":"object","required":["receipt"],"properties":{"receipt":{"$ref":"#/components/schemas/org.hypercerts.funding.getReceipt.receiptView"}}}, "org.hypercerts.funding.listReceipts.output": {"type":"object","required":["receipts"],"properties":{"receipts":{"type":"array","items":{"$ref":"#/components/schemas/org.hypercerts.funding.getReceipt.receiptView"}},"cursor":{"type":"string","description":"Opaque cursor for the next page; omitted when there is no next page."}}}, diff --git a/.changeset/lexicon-1-6-0.md b/.changeset/lexicon-1-6-0.md new file mode 100644 index 0000000..f38f63e --- /dev/null +++ b/.changeset/lexicon-1-6-0.md @@ -0,0 +1,5 @@ +--- +'@hypercerts-org/happyview-modules': minor +--- + +Validate records against `@hypercerts-org/lexicon` 1.6.0 (was 1.5.0). Records may now carry the optional `langs` field and `app.certified.signature.defs#createdVia` signatures, and funding receipts may omit `amount` and `currency`. Records using these are accepted and served unchanged; no record that validated before is rejected. Operators must reinstall the bundle for the running indexer to use the new Lexicons. diff --git a/docs/coverage.json b/docs/coverage.json index 9074e5c..a1af9a8 100644 --- a/docs/coverage.json +++ b/docs/coverage.json @@ -1,7 +1,7 @@ { "source": { "apiManifest": "happyview-modules/manifest.json", - "pinnedLexiconPackage": "1.5.0" + "pinnedLexiconPackage": "1.6.0" }, "runtimeValidation": "not-assessed", "deploymentValidation": "not-assessed", diff --git a/docs/openapi.json b/docs/openapi.json index eba213c..e677dfd 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -7887,7 +7887,7 @@ }, "org.hypercerts.context.attachment.main": { "type": "record", - "description": "An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation)." + "description": "An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation) or related to an account profile." }, "org.hypercerts.context.getAttachment.attachmentView": { "type": "object", @@ -8273,7 +8273,7 @@ }, "org.hypercerts.funding.receipt.main": { "type": "record", - "description": "Records a funding receipt for a payment from one user to another user. It may be recorded by the recipient, by the sender, or by a third party. The sender may remain anonymous." + "description": "Records a payment from a sender to a recipient. Any party may record it, and the sender may stay anonymous. When the sender chose the recipient, record one receipt to the final recipient even if platforms or hosts passed the funds on. When an intermediary chose (regranting), record the payment into it and each onward payment as separate receipts. A receipt may be updated in place under the same record key: its URI does not change, so references by URI keep resolving, but a strongRef (as likes and reposts use) still pins the earlier CID, and signatures bind to content and must be renewed. An earlier version cannot be recalled from readers that kept it." }, "org.hypercerts.funding.getReceipt.receiptView": { "type": "object", @@ -8498,6 +8498,6 @@ } } }, - "x-hypercerts-source": "happyview-modules/manifest.json; @hypercerts-org/lexicon@1.5.0", + "x-hypercerts-source": "happyview-modules/manifest.json; @hypercerts-org/lexicon@1.6.0", "x-hypercerts-unresolved-references": [] } diff --git a/docs/sources/index.json b/docs/sources/index.json index 8fed6be..9b8daad 100644 --- a/docs/sources/index.json +++ b/docs/sources/index.json @@ -1,6 +1,6 @@ { "apiManifest": "happyview-modules/manifest.json", - "pinnedLexiconPackage": "1.5.0", + "pinnedLexiconPackage": "1.6.0", "sourcePolicy": "Explorer operations are the query/procedure Lexicons declared by modules in happyview-modules/manifest.json. Referenced schemas are resolved from that manifest and its pinned Lexicon package; no remote refs are fetched.", "runtimeValidation": "not-assessed", "deploymentValidation": "not-assessed", diff --git a/docs/sources/lexicons/app.certified.actor.organization.json b/docs/sources/lexicons/app.certified.actor.organization.json index 55652f6..ca76404 100644 --- a/docs/sources/lexicons/app.certified.actor.organization.json +++ b/docs/sources/lexicons/app.certified.actor.organization.json @@ -77,6 +77,15 @@ ], "description": "Long-form description of the organization, such as its mission, history, or detailed project narrative. An inline string for plain text or markdown, a Leaflet linear document record embedded directly, or a strong reference to an existing document record." }, + "langs": { + "type": "array", + "description": "Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, "visibility": { "type": "string", "knownValues": [ diff --git a/docs/sources/lexicons/app.certified.actor.profile.json b/docs/sources/lexicons/app.certified.actor.profile.json index 38a46e5..93fa637 100644 --- a/docs/sources/lexicons/app.certified.actor.profile.json +++ b/docs/sources/lexicons/app.certified.actor.profile.json @@ -30,6 +30,15 @@ "maxGraphemes": 20, "maxLength": 200 }, + "langs": { + "type": "array", + "description": "Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, "website": { "type": "string", "format": "uri", diff --git a/docs/sources/lexicons/app.certified.signature.defs.json b/docs/sources/lexicons/app.certified.signature.defs.json index 103a5c2..a5577df 100644 --- a/docs/sources/lexicons/app.certified.signature.defs.json +++ b/docs/sources/lexicons/app.certified.signature.defs.json @@ -1,22 +1,23 @@ { "lexicon": 1, "id": "app.certified.signature.defs", - "description": "Common type definitions for cryptographic signatures attached to records, per the ATProtocol Attestation Specification.", + "description": "Common type definitions for cryptographic signatures attached to records, per the ATProtocol Attestation Specification. Each signature's `$type` says what it attests.", "defs": { "list": { "type": "array", - "description": "Reusable array of cryptographic signatures attesting to a record's content. Open union of inline signatures and strong references to remote attestation proof records.", + "description": "Reusable array of cryptographic signatures on a record. Each entry's `$type` says what it attests. The union is open: other applications may define their own signature types, and consumers ignore types they do not recognize.", "items": { "type": "union", "refs": [ "app.certified.signature.defs#inline", + "app.certified.signature.defs#createdVia", "com.atproto.repo.strongRef" ] } }, "inline": { "type": "object", - "description": "Inline attestation signature embedded directly in a record. Conforms to the ATProtocol Attestation Specification: the signed input is the 36-byte CIDv1 (dag-cbor + SHA-256) of the record with the `signatures` field removed and a temporary `$sig` metadata object (containing `$type` and the housing repository DID) inserted before canonical DAG-CBOR encoding. ECDSA with the low-S variant per BIP-0062 is required; the curve (P-256 or K-256) is determined by the multicodec prefix of the verification method's `publicKeyMultibase`.", + "description": "Inline attestation signature embedded directly in a record. Conforms to the ATProtocol Attestation Specification: the signed input is the 36-byte CIDv1 (dag-cbor + SHA-256) of the record with the `signatures` field removed and a temporary `$sig` metadata object (containing `$type`, `key` and the housing repository DID) inserted before canonical DAG-CBOR encoding. ECDSA with the low-S variant per BIP-0062 is required; the curve (P-256 or K-256) is determined by the multicodec prefix of the verification method's `publicKeyMultibase`.", "required": [ "signature", "key" @@ -32,6 +33,25 @@ "maxLength": 512 } } + }, + "createdVia": { + "type": "object", + "description": "Inline signature by the application that wrote this version of the record. It does not mean the application endorses the content. A record should carry at most one `#createdVia` signature; applications enforce this, `#list` validation does not. Signed exactly like `#inline`: `$sig` is this signature entry without its `signature` field (so `$type` and `key`), plus `repository`, the DID of the repository that holds the record.", + "required": [ + "signature", + "key" + ], + "properties": { + "signature": { + "type": "bytes", + "description": "ECDSA signature bytes (raw r,s) over the 36-byte CID of the record. Low-S variant per BIP-0062 is mandatory." + }, + "key": { + "type": "string", + "description": "DID verification method of the application's signing key. It should be in the application's own DID document, preferably a did:web on the application's domain, so that the DID names the application.", + "maxLength": 512 + } + } } } } diff --git a/docs/sources/lexicons/org.hypercerts.claim.activity.json b/docs/sources/lexicons/org.hypercerts.claim.activity.json index e9879c5..77a3e34 100644 --- a/docs/sources/lexicons/org.hypercerts.claim.activity.json +++ b/docs/sources/lexicons/org.hypercerts.claim.activity.json @@ -42,6 +42,15 @@ ], "description": "Long-form description of the activity. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record." }, + "langs": { + "type": "array", + "description": "Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, "image": { "type": "union", "refs": [ diff --git a/docs/sources/lexicons/org.hypercerts.collection.json b/docs/sources/lexicons/org.hypercerts.collection.json index 6b84fe7..690d2b5 100644 --- a/docs/sources/lexicons/org.hypercerts.collection.json +++ b/docs/sources/lexicons/org.hypercerts.collection.json @@ -53,6 +53,15 @@ ], "description": "Long-form description of the collection. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record." }, + "langs": { + "type": "array", + "description": "Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, "avatar": { "type": "union", "refs": [ diff --git a/docs/sources/lexicons/org.hypercerts.context.attachment.json b/docs/sources/lexicons/org.hypercerts.context.attachment.json index 6df8c5d..ddeeea0 100644 --- a/docs/sources/lexicons/org.hypercerts.context.attachment.json +++ b/docs/sources/lexicons/org.hypercerts.context.attachment.json @@ -4,7 +4,7 @@ "defs": { "main": { "type": "record", - "description": "An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation).", + "description": "An attachment providing commentary, context, evidence, or documentary material related to a hypercert record (e.g. an activity, project, claim, or evaluation) or related to an account profile.", "key": "tid", "record": { "type": "object", @@ -15,7 +15,7 @@ "properties": { "subjects": { "type": "array", - "description": "References to the subject(s) the attachment is connected to—this may be an activity claim, outcome claim, measurement, evaluation, or even another attachment. This is optional as the attachment can exist before the claim is recorded.", + "description": "References to the subject(s) the attachment is about: an activity claim, a collection, a measurement, an evaluation, another attachment (for a comment on it), or an account profile (app.certified.actor.profile). A standalone update by its author points at the author's own profile: it is an update about the author. Optional: omit it only when the attachment is recorded before the claim it will support.", "items": { "type": "ref", "ref": "com.atproto.repo.strongRef" @@ -26,6 +26,7 @@ "type": "string", "description": "The type of attachment. Values beyond the known set are permitted.", "knownValues": [ + "update", "report", "audit", "evidence", @@ -74,6 +75,15 @@ ], "description": "Long-form description of the attachment. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record." }, + "langs": { + "type": "array", + "description": "Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, "location": { "type": "ref", "ref": "com.atproto.repo.strongRef", @@ -88,6 +98,11 @@ "ref": "com.atproto.repo.strongRef" } }, + "capturedAt": { + "type": "string", + "format": "datetime", + "description": "Client-declared time when the attached material was captured (e.g. when a photo was taken), as distinct from createdAt. Omit if capture time is unknown, if only a local time without timezone offset or only a date is known, or if no single capture time applies. Not a coverage interval." + }, "createdAt": { "type": "string", "format": "datetime", diff --git a/docs/sources/lexicons/org.hypercerts.entity.feature.json b/docs/sources/lexicons/org.hypercerts.entity.feature.json index 22fe9de..d7da5f3 100644 --- a/docs/sources/lexicons/org.hypercerts.entity.feature.json +++ b/docs/sources/lexicons/org.hypercerts.entity.feature.json @@ -37,6 +37,15 @@ "com.atproto.repo.strongRef" ] }, + "langs": { + "type": "array", + "description": "Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field.", + "maxLength": 3, + "items": { + "type": "string", + "format": "language" + } + }, "locations": { "type": "array", "description": "Optional published spatial representations of this feature. Each referenced record must conform with app.certified.location. Multiple entries are alternative representations of the same subject at different precisions or encodings — never different places. Genuinely different places are either one MultiPolygon inside a single location record, or separate features. Writers SHOULD list entries in publisher-preferred order, most preferred first. All referenced locations are public once published: for sensitive subjects, publish only a coarse representation and keep exact geometry unpublished. An empty or absent array is valid: the subject's geometry is unpublished or not applicable.", diff --git a/docs/sources/lexicons/org.hypercerts.funding.receipt.json b/docs/sources/lexicons/org.hypercerts.funding.receipt.json index 71a22a0..4b27dad 100644 --- a/docs/sources/lexicons/org.hypercerts.funding.receipt.json +++ b/docs/sources/lexicons/org.hypercerts.funding.receipt.json @@ -4,20 +4,18 @@ "defs": { "main": { "type": "record", - "description": "Records a funding receipt for a payment from one user to another user. It may be recorded by the recipient, by the sender, or by a third party. The sender may remain anonymous.", + "description": "Records a payment from a sender to a recipient. Any party may record it, and the sender may stay anonymous. When the sender chose the recipient, record one receipt to the final recipient even if platforms or hosts passed the funds on. When an intermediary chose (regranting), record the payment into it and each onward payment as separate receipts. A receipt may be updated in place under the same record key: its URI does not change, so references by URI keep resolving, but a strongRef (as likes and reposts use) still pins the earlier CID, and signatures bind to content and must be renewed. An earlier version cannot be recalled from readers that kept it.", "key": "tid", "record": { "type": "object", "required": [ "to", - "amount", - "currency", "createdAt" ], "properties": { "from": { "type": "union", - "description": "The sender of the funds (a free-text string, an account DID, or a strong reference to a record). Optional — omit to represent anonymity.", + "description": "The sender of the funds (a free-text string, an account DID, or a strong reference to a record). Optional — omit to represent anonymity. Name a sender only if they chose to be named: from can be added later by updating the receipt in place, but removing it later only hides the name from the current version, and an onchain transactionId still names the sending wallet.", "refs": [ "#text", "app.certified.defs#did", @@ -33,29 +31,68 @@ "com.atproto.repo.strongRef" ] }, + "via": { + "type": "union", + "description": "Optional intermediary that facilitated or processed the payment (funding platform, payment servicer, broker).", + "refs": [ + "#text", + "app.certified.defs#did", + "com.atproto.repo.strongRef" + ] + }, + "type": { + "type": "string", + "description": "What the payment is: a donation (a gift from the sender), a match (funds a matching pool allocated on the strength of other gifts) or a grant (funds awarded through a selection process). Values beyond the known set are permitted. Omit if unknown.", + "maxLength": 50, + "knownValues": [ + "donation", + "match", + "grant" + ] + }, "amount": { "type": "string", - "description": "Amount of funding received as a numeric string (e.g. '1000.50').", + "description": "Gross amount the sender paid, before fees, as a numeric string (e.g. '1000.50'). Omit if unknown, and set netAmount instead.", "maxLength": 50 }, "currency": { "type": "string", - "description": "Currency of the payment (e.g. EUR, USD, ETH).", + "description": "Currency of amount: an ISO 4217 code for fiat (e.g. EUR), a token ticker for digital assets (e.g. USDC). This is what marks the funds as fiat or digital. Set it whenever amount is set.", "maxLength": 10 }, - "paymentRail": { + "netAmount": { "type": "string", - "description": "How the funds were transferred (e.g. bank_transfer, credit_card, onchain, cash, check, payment_processor).", + "description": "What the recipient received after fees and conversion, as a numeric string in netCurrency.", "maxLength": 50 }, + "netCurrency": { + "type": "string", + "description": "Currency of netAmount: an ISO 4217 code for fiat, a token ticker for digital assets. Set it whenever netAmount is set.", + "maxLength": 10 + }, + "paymentRail": { + "type": "string", + "description": "How the sender paid. Use 'payment_processor' only when the underlying method is unknown.", + "maxLength": 50, + "knownValues": [ + "onchain", + "bank_transfer", + "card", + "direct_debit", + "mobile_money", + "payment_processor", + "cash", + "check" + ] + }, "paymentNetwork": { "type": "string", - "description": "Optional network within the payment rail (e.g. arbitrum, ethereum, sepa, visa, paypal).", + "description": "Where transactionId can be looked up: the chain for onchain payments, preferably as a CAIP-2 ID (e.g. 'eip155:1'), otherwise the processor or scheme (e.g. stripe, sepa). Set it whenever transactionId is a transaction hash.", "maxLength": 50 }, "transactionId": { "type": "string", - "description": "Identifier of the underlying payment transaction (e.g. bank reference, onchain transaction hash, or processor-specific ID). Use paymentNetwork to specify the network where applicable.", + "description": "ID of the sender's payment, not of a platform's later payout: a transaction hash for onchain payments, otherwise the processor's or scheme's reference. Receipts are public: prefer opaque processor IDs to bank references, and note that a hash reveals the sender's wallet even when from is omitted.", "maxLength": 256 }, "for": { diff --git a/happyview-modules/package.json b/happyview-modules/package.json index 70994bd..0b0976b 100644 --- a/happyview-modules/package.json +++ b/happyview-modules/package.json @@ -8,7 +8,7 @@ "@atcute/cid": "2.4.1", "@atproto/lexicon": "0.6.2", "@atproto/syntax": "0.5.4", - "@hypercerts-org/lexicon": "1.5.0" + "@hypercerts-org/lexicon": "1.6.0" }, "scripts": { "lint:js": "eslint --max-warnings=0 --report-unused-disable-directives .", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 15d3051..3951420 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,8 +61,8 @@ importers: specifier: 0.5.4 version: 0.5.4 '@hypercerts-org/lexicon': - specifier: 1.5.0 - version: 1.5.0(@atproto/xrpc@0.8.13) + specifier: 1.6.0 + version: 1.6.0(@atproto/xrpc@0.8.13) devDependencies: '@eslint/js': specifier: ^10.0.1 @@ -553,8 +553,8 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@hypercerts-org/lexicon@1.5.0': - resolution: {integrity: sha512-zg7//t8Mghrb6Z2fsSE0dIaNlGn6vBC5Hy8s7xodF7Fb1cpxUA3iLvzfvGQfR7yNV62o4bUyLlPE6Ez10eqfaQ==} + '@hypercerts-org/lexicon@1.6.0': + resolution: {integrity: sha512-lJJzCgSFJkGhsOXBtVJOnQUgwaodMQD+0a10PryANuA77es0O34o1+I7BMyXVcMm/fW/6+hYvBeWpYsRXWpQ0g==} peerDependencies: '@atproto/xrpc': '*' @@ -3135,7 +3135,7 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@hypercerts-org/lexicon@1.5.0(@atproto/xrpc@0.8.13)': + '@hypercerts-org/lexicon@1.6.0(@atproto/xrpc@0.8.13)': dependencies: '@atproto/lexicon': 0.6.2 '@atproto/xrpc': 0.8.13