@percayso-community/cayso-contracts 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +114 -0
  3. package/dist/assertion.d.ts +867 -0
  4. package/dist/assertion.js +63 -0
  5. package/dist/assurance.d.ts +353 -0
  6. package/dist/assurance.js +551 -0
  7. package/dist/citizen-market.d.ts +468 -0
  8. package/dist/citizen-market.js +16 -0
  9. package/dist/citizenship.d.ts +215 -0
  10. package/dist/citizenship.js +26 -0
  11. package/dist/client.d.ts +288 -0
  12. package/dist/client.js +370 -0
  13. package/dist/commercial-payment.d.ts +243 -0
  14. package/dist/commercial-payment.js +16 -0
  15. package/dist/contract-schema.generated.d.ts +14 -0
  16. package/dist/contract-schema.generated.js +3107 -0
  17. package/dist/errors.d.ts +171 -0
  18. package/dist/errors.js +28 -0
  19. package/dist/index.d.ts +621 -0
  20. package/dist/index.js +624 -0
  21. package/dist/marketplace-receipt.d.ts +306 -0
  22. package/dist/marketplace-receipt.js +116 -0
  23. package/dist/marketplace-settlement.d.ts +298 -0
  24. package/dist/marketplace-settlement.js +16 -0
  25. package/dist/money.d.ts +84 -0
  26. package/dist/money.js +34 -0
  27. package/dist/organisation.d.ts +60 -0
  28. package/dist/organisation.js +16 -0
  29. package/dist/purchase.d.ts +531 -0
  30. package/dist/purchase.js +107 -0
  31. package/dist/restriction.d.ts +262 -0
  32. package/dist/restriction.js +316 -0
  33. package/dist/routes.d.ts +155 -0
  34. package/dist/routes.js +128 -0
  35. package/dist/schema-types.d.ts +101 -0
  36. package/dist/schema-types.js +16 -0
  37. package/dist/schema.d.ts +24 -0
  38. package/dist/schema.js +16 -0
  39. package/dist/wallet.d.ts +92 -0
  40. package/dist/wallet.js +59 -0
  41. package/package.json +41 -0
@@ -0,0 +1,621 @@
1
+ /**
2
+ * `@percayso-community/cayso-contracts` — the versioned capability contract surface through which
3
+ * anything outside this repository reads a wallet (`cayso.wallet`).
4
+ *
5
+ * This barrel is the *only* public surface of the package: the record and
6
+ * response types, the closed failure-reason union, the assertion claims and the
7
+ * route constants land here across slices 5–7 (the assertion claims arrived in
8
+ * slice 7), and the thin client ships from the separate `./client` entry point
9
+ * in slice 8. Importing this package must do
10
+ * nothing but hand back its exports — no server, no connection, no environment
11
+ * read (CLAUDE.md: packages have no side effects on import).
12
+ *
13
+ * The assurance profile (CAY-0029) joins them, and is the first contract here to
14
+ * carry runtime values as well as types — the evidence statements and the
15
+ * acceptance policy are data a consumer and an issuer both have to read, and a
16
+ * type is erased before either can. The trust envelope (CAY-0030) adds the second
17
+ * set: the assertion header and envelope types, and the three clock constants an
18
+ * issuer sizes its credentials against.
19
+ *
20
+ * What the envelope adds here is the PIPER-FACING half of CAY-0030 and no more.
21
+ * The claims, the header, the scope vocabulary and the rotation obligation are a
22
+ * consumer's business and are published. The issuer registry — who we trust, under
23
+ * which key ids, serving which environment — is Cayso's own configuration and is
24
+ * deliberately NOT here: publishing our trust configuration would be publishing a
25
+ * map of what to attack, and it lives in the private `@cayso/identity` instead.
26
+ *
27
+ * The issued-but-uncaptured purchase (CAY-0033) is the newest: the status a
28
+ * purchase takes when its cents landed and its capture did not, which is neither a
29
+ * success nor a failure and may still become either; the bound on how many times
30
+ * capture is attempted before only an operator can move it; and the closed reason a
31
+ * compensated purchase finally carries. Its one runtime value is that bound.
32
+ *
33
+ * Purchase replay and continuation (CAY-0032) is the record before it: what a repeat `POST`
34
+ * with the same idempotency key does — it REPLAYS the original authorisation, at
35
+ * the original price — which statuses are terminal, the cancel path available to a
36
+ * holder, and what expiry releases. It carries three runtime values: the terminal
37
+ * status list and its predicate, and the reservation window a consumer sizes its
38
+ * confirmation page against.
39
+ *
40
+ * Citizenship provisioning (CAY-0031) is the contract before it: an explicit,
41
+ * idempotent call that provisions a wallet and its sign-up grant as one unit, and
42
+ * a separate read by which a consumer can ask whether a citizen has been
43
+ * provisioned WITHOUT provisioning them. It carries one runtime value — the
44
+ * `not_provisioned` wire code — and no figures: the grant's amount and its
45
+ * restriction period are FIELDS a consumer reads at runtime, sourced from the
46
+ * canon PRD through configuration, never literals here.
47
+ *
48
+ * The restricted-Cayso capability policy (CAY-0035) is the newest, and it is the
49
+ * only contract here that is a POLICY rather than a shape: four capabilities
50
+ * against four kinds of holding, every one of the sixteen cells written out as
51
+ * permitted, refused or explicitly open. It settles what a restriction actually
52
+ * restricts — cash-out, not spending — and it publishes the one cell the canon has
53
+ * not decided AS undecided rather than guessing it. It is published because a
54
+ * consumer rendering the restricted/unrestricted split on a balance cannot say what
55
+ * that split MEANS for a holder without it, and each consumer inventing its own
56
+ * answer is how two surfaces end up telling a citizen different things about the
57
+ * same cents. It is compile-time data with no side effects, and it enforces
58
+ * nothing.
59
+ *
60
+ * This is the *Piper-facing surface only*. Peer types, admin types, holdings and
61
+ * carves are deliberately not exported here; they are not a consumer's business.
62
+ * And it carries **no numbers** — amounts, rates, tiers, schedules and thresholds
63
+ * live in the canon PRD and are read from one place, never restated here.
64
+ */
65
+ /**
66
+ * The independent semantic version of this contract surface.
67
+ *
68
+ * It is declared here and must agree with the package's own `version` field —
69
+ * a test asserts the two never drift. This is deliberately *not* a repo-wide
70
+ * constant shared with anything else: independent versioning is precisely what
71
+ * this money surface gains that Piper's own contracts lack, since theirs share
72
+ * one global version bumped across all twenty-two together (CAY-0026).
73
+ *
74
+ * `0.22.0` → `0.23.0` publishes the two money-grade marketplace operations and
75
+ * CAY-0082 §7's closed refusal unions (CAY-0083 §3, #303), and it is BREAKING because
76
+ * three closed tables grew:
77
+ *
78
+ * - **`ContractOperation` gains `'settle-marketplace-order'` and
79
+ * `'settle-marketplace-refund'`**, so every total map over the vocabulary needs
80
+ * their entries.
81
+ * - **`ASSURANCE_POLICY` gains their two rows, both money-grade allowlists** at the
82
+ * purchase path's bar. `'dev-bypass'` is `'refused'` at both, and a future method
83
+ * is admissible at neither without a policy decision (CAY-0029).
84
+ * - **`CaysoApiErrorCode` gains {@link MarketplaceOrderRefusal} and
85
+ * {@link MarketplaceRefundRefusal} by reference**, and with them the codes they
86
+ * add.
87
+ *
88
+ * The shapes are additive. {@link MarketplaceOrderRequest} and
89
+ * {@link MarketplaceRefundRequest} each carry one {@link StoreSignedStatement}: the
90
+ * exact bytes Store Platform signed and the signature over them, with nothing beside
91
+ * them, so the idempotency key, the price and who is paid are never the caller's
92
+ * word. {@link MarketplaceOrderResponse} is a receipt narrowed to a sale's, or one
93
+ * refusal; {@link MarketplaceRefundResponse} is a receipt narrowed to a refund's, or
94
+ * one refusal. No route serves either operation yet.
95
+ *
96
+ * `0.21.0` → `0.22.0` publishes the marketplace status read (CAY-0083 §2, #302), and
97
+ * it is BREAKING because two closed tables grew:
98
+ *
99
+ * - **`ContractOperation` gains `'read-marketplace-receipt'`**, so every total map
100
+ * over the vocabulary — `ASSURANCE_POLICY` among them — needs its entry.
101
+ * - **`ASSURANCE_POLICY` gains its row, read-scope (`'not-required'`)**: the read
102
+ * moves nothing and writes no row of its own, and the bar was applied when the
103
+ * sale or refund it reports on was presented.
104
+ *
105
+ * The shapes are additive. {@link MarketplaceReceiptReadRequest} carries the
106
+ * idempotency key and nothing else, because the paying wallet is the verified
107
+ * subject's own. {@link MarketplaceReceiptReadResponse} is a receipt, "no movement
108
+ * for this key", or a refusal from {@link MarketplaceReceiptReadRefusal} — and
109
+ * never "pending", because a movement is written or it is not (CAY-0023). The
110
+ * refusal joins `CaysoApiErrorCode` by reference and adds no code. No route serves
111
+ * the read yet, and the two money-grade marketplace operations are not published
112
+ * here (#303).
113
+ *
114
+ * `0.20.0` → `0.21.0` publishes the marketplace receipt (CAY-0083 §1, #301), and it
115
+ * is BREAKING because one closed union grew:
116
+ *
117
+ * - **`CaysoApiErrorCode` gains `receipt_signing_not_configured`**: the deployment
118
+ * holds no key it may sign a receipt with, so it writes no marketplace sale or
119
+ * refund. Published before the checkout that answers it (#303).
120
+ *
121
+ * The rest is additive. {@link MarketplaceReceipt} is a statement and Cayso's
122
+ * signature over its encoding, and the statement is one of four shapes — a
123
+ * third-party sale, a house-publisher charge, and the refund of each — so a
124
+ * house-publisher statement has no publisher leg to fill. It names wallet ids and
125
+ * never a Percayso identity. Two values arrive with it:
126
+ * {@link MARKETPLACE_RECEIPT_SIGNATURE_ALGORITHM}, and
127
+ * {@link encodeMarketplaceReceiptStatement}, the one encoding the signer and Store
128
+ * Platform both compute the signature over. No key, key set or verifier is here;
129
+ * no route serves a receipt yet (#302, #303).
130
+ *
131
+ * `0.19.0` → `0.20.0` serves the Treasury's buy-back (CAY-0080 slice 10, #291), and it
132
+ * is BREAKING because three closed tables grew:
133
+ *
134
+ * - **`ROUTES` gains `requestBuyBack`**, `POST /api/buy-backs`.
135
+ * `OPERATION_FOR_ROUTE` maps it to `'request-buy-back'`, the operation `0.17.0`
136
+ * classified, and the client gains `requestBuyBack`.
137
+ * - **{@link BuyBackRefusal} gains `eligible_sterling_insufficient`**: the Treasury's
138
+ * eligible sterling cannot meet the request, which is refused whole and never
139
+ * rationed (§2.3), pending Simon James's answer to Open decision I. There is still
140
+ * no per-holder limit reason: figure 11 is his, and until he answers the buy-back
141
+ * is shut by configuration.
142
+ * - **`CaysoApiErrorCode` gains `buy_back_not_configured` and
143
+ * `sterling_not_observed`**. The first is the buy-back's closed door, on a
144
+ * deployment with no buy-back store or with one of its figures unset. The second
145
+ * is a deployment that has never observed sterling; the purchase path already
146
+ * answered it (#246), and the union now says so.
147
+ *
148
+ * The buy-back's request and answer shapes are the ones `0.17.0` published, unchanged.
149
+ * The payout stays behind the fake gateway (§3.4) and adds nothing here.
150
+ *
151
+ * `0.18.0` → `0.19.0` settles a match (CAY-0080 slice 9, #290), and it is BREAKING
152
+ * because two closed unions grew:
153
+ *
154
+ * - **{@link QuoteWithdrawalReason} gains `authorisation_refused`**: a bid that met
155
+ * an ask and whose holder's sterling could not be authorised for the match leaves
156
+ * the book with this reason, and no cents move (CAY-0080 §3.2, step 2). A
157
+ * consumer's exhaustive rendering of a withdrawn quote must place it.
158
+ * - **{@link QuotePlacementRefusal} gains `sterling_leg_unavailable`**: the quote met
159
+ * the book and the sterling leg could not be reached, so nothing was written and
160
+ * the placement may be retried under the same key.
161
+ *
162
+ * The match's settlement — its capture, its bounded retries and an operator's
163
+ * re-attempt or compensation — is an operator surface and adds nothing here.
164
+ *
165
+ * `0.17.0` → `0.18.0` serves the citizen market's book (CAY-0080 slice 8, #289), and
166
+ * it is BREAKING because three closed tables grew.
167
+ *
168
+ * - **`ROUTES` gains `citizenMarket`, `placeQuote` and `withdrawQuote`**:
169
+ * `GET /api/citizen-market`, `POST /api/quotes` and `POST /api/quote-withdrawals`.
170
+ * `OPERATION_FOR_ROUTE` maps the two writes to `'place-quote'` and
171
+ * `'withdraw-quote'`, and the client gains `getCitizenMarket`, `placeQuote` and
172
+ * `withdrawQuote`, one method for each route. The buy-back is not served yet.
173
+ * - **`ContractOperation` gains `'read-citizen-market'`**, the read beside the two
174
+ * writes, with no assurance bar, as `'read-own-wallet'` has none.
175
+ * - **`CaysoApiErrorCode` gains `citizen_market_not_configured`**, the market's
176
+ * closed door on a deployment with no store or an unset figure. It is none of the
177
+ * market's refusal unions' members.
178
+ *
179
+ * The book's read shapes are new and additive: {@link CitizenMarketResponse} and
180
+ * {@link CitizenMarketView} — the published value and its band, both bounds per
181
+ * quote unit, the best bid and ask as {@link BookLevel}s, and the caller's own
182
+ * quotes as {@link OwnQuote}s, a withdrawn one carrying its closed
183
+ * {@link QuoteWithdrawalReason}. No match price, no feed and no history (Open
184
+ * decision F). The refusal unions of `0.17.0` do not change.
185
+ *
186
+ * `0.16.0` → `0.17.0` is the citizen market's contract and acceptance policy
187
+ * (CAY-0080 slices 3 and 4, #286), and it is BREAKING because two closed unions
188
+ * grew. No route is added and no migration is behind it: the operations are
189
+ * classified before they are served, as the commercial payment's was.
190
+ *
191
+ * - **`ContractOperation` gains `'place-quote'`, `'withdraw-quote'` and
192
+ * `'request-buy-back'`**, each money-grade in `ASSURANCE_POLICY` — `'document'`
193
+ * and `'document-and-biometric'`, never `'dev-bypass'` (Open decision Q). A
194
+ * consumer's exhaustive handling of the operation vocabulary must place them.
195
+ * - **`CaysoApiErrorCode` gains the market's refusals by reference**:
196
+ * {@link QuotePlacementRefusal}, which is CAY-0080 §1.6's fixed set
197
+ * ({@link QuoteEntryRefusal}) beside the key-reuse refusal,
198
+ * {@link QuoteWithdrawalRefusal} and {@link BuyBackRefusal}. The buy-back names
199
+ * no eligible-sterling shortfall and no per-holder limit, because both are
200
+ * Simon James's (Open decision I, figure 11).
201
+ * - **The request and answer shapes are new and additive**: {@link QuoteRequest}
202
+ * and {@link QuoteResponse}, {@link QuoteWithdrawalRequest} and
203
+ * {@link QuoteWithdrawalResponse}, {@link BuyBackRequest} and
204
+ * {@link BuyBackResponse}, each discriminated by `outcome`. No request names a
205
+ * wallet: the holder is the verified subject.
206
+ *
207
+ * Under semver below `1.0.0` the minor is where a breaking change goes, so the minor
208
+ * moves and the patch does not.
209
+ *
210
+ * `0.15.0` → `0.16.0` serves the commercial payment's Authorised-User route (CAY-0079,
211
+ * #284), and it is BREAKING because a closed union SHRANK.
212
+ *
213
+ * - **`CaysoApiErrorCode` loses `payment_allowance_route_not_served`.** It answered
214
+ * `authority: 'payment-allowance'` until the Authorised-User route shipped, and
215
+ * that route is now served: a caller declaring it is held to the pair's payment
216
+ * allowance and the Signatory / Authorised-User threshold, and is answered in
217
+ * `CommercialPaymentResponse`. A consumer that rendered the retired code must
218
+ * drop the case; nothing produces it.
219
+ *
220
+ * `CommercialPaymentRefusal` does not change: the Authorised-User route's members were
221
+ * on it from `0.14.0`, and the route now produces them.
222
+ *
223
+ * `0.14.0` → `0.15.0` serves the commercial payment, on the mandate route (CAY-0079
224
+ * slice 6, #283), and it is BREAKING because two closed tables grew.
225
+ *
226
+ * - **`ROUTES` gains `commercialPayment`**, `POST /api/commercial-payments`, and
227
+ * `OPERATION_FOR_ROUTE` maps it to `'make-commercial-payment'`. The client
228
+ * gains `makeCommercialPayment`, one method for the one route.
229
+ * - **`CaysoApiErrorCode` gains two seam codes.**
230
+ * `commercial_payment_store_not_configured` is the route's closed door on a
231
+ * deployment not told enough to make a payment. `payment_allowance_route_not_served`
232
+ * is the answer to `authority: 'payment-allowance'` until the Authorised-User
233
+ * route ships second (Open decision H); nothing is checked against an allowance
234
+ * and the mandate route is never tried instead. Neither is a
235
+ * `CommercialPaymentRefusal`, because each describes the deployment and not the
236
+ * payment.
237
+ *
238
+ * `CommercialPaymentRefusal` itself does not change. The route answers its members,
239
+ * including `assurance_not_money_grade` from the money gate, in the
240
+ * `CommercialPaymentRefused` envelope.
241
+ *
242
+ * `0.13.0` → `0.14.0` is the commercial payment's contract (CAY-0079, #281), and it
243
+ * is BREAKING because two closed unions grew. No route is added: the operation is
244
+ * classified before it is served, as `'provision-citizenship'` was, and the route is
245
+ * CAY-0079's slice 6.
246
+ *
247
+ * - **`ContractOperation` gains `'make-commercial-payment'`**, an Organisation
248
+ * paying a Citizen. Its acceptance policy is money-grade — `'document'` and
249
+ * `'document-and-biometric'`, never `'dev-bypass'` — the purchase path's bar. A
250
+ * consumer's exhaustive handling of the operation vocabulary must place it.
251
+ * - **`CaysoApiErrorCode` gains {@link CommercialPaymentRefusal} by reference**:
252
+ * CAY-0079 §3's set, including the Authorised-User route's reasons, which
253
+ * nothing can produce until that route ships second (Open decision H). They are
254
+ * here from the first version so that they are never a later change to a closed
255
+ * union.
256
+ * - **The request and answer shapes are new and additive**:
257
+ * {@link CommercialPaymentRequest}, and {@link CommercialPaymentResponse}
258
+ * discriminated by `outcome` as `'paid'` or `'refused'`. There is no status,
259
+ * because a commercial payment is one movement or nothing.
260
+ *
261
+ * Under semver below `1.0.0` the minor is where a breaking change goes, so the minor
262
+ * moves and the patch does not.
263
+ *
264
+ * `0.12.0` → `0.13.0` is erasure resolving a holder's in-flight purchases (CAY-0085,
265
+ * H8-R2), and it is BREAKING because a closed union grew:
266
+ *
267
+ * - **`PurchaseFailureReason` gains `'holder_erased'`.** The union is closed and
268
+ * consumers switch on it exhaustively, so a new member is breaking by construction
269
+ * (CAY-0023) — which is the property that makes it safe to add. Erasing a holder's
270
+ * binding now first ends every purchase of theirs that was authorised and had
271
+ * issued nothing, with this reason, and a settlement delivery for a wallet with no
272
+ * binding is refused with it rather than issuing into a wallet bound to nobody. A
273
+ * consumer polling such a purchase sees it end `failed` with a member it can
274
+ * render.
275
+ *
276
+ * Under semver below `1.0.0` the minor is where a breaking change goes, so the minor
277
+ * moves and the patch does not.
278
+ *
279
+ * `0.11.0` → `0.12.0` is the founder claim's contract (CAY-0081, #252), and it is
280
+ * BREAKING because two closed unions grew. The operation was classified first and is
281
+ * served in the same version, so no release carries the operation without its route.
282
+ *
283
+ * - **`ROUTES` gains `citizenshipFounderClaim`**, `POST /api/citizenship/founder-claim`,
284
+ * and the client gains `claimFounderWallet()` beside it. Neither takes a
285
+ * parameter: the founder wallet is named by the reference inside the signed
286
+ * assertion, and the Citizen by its subject. It answers
287
+ * {@link CitizenshipFounderClaimed} alone, with no `terms`, because a founder is
288
+ * never offered a sign-up grant.
289
+ * - **`ContractOperation` gains `'claim-founder-wallet'`.** Its acceptance policy
290
+ * accepts `'document-and-biometric'` alone, stricter than any other operation,
291
+ * because a founder completes full identity proofing before claiming. An issuer
292
+ * minting it must also mint the new claim beside it.
293
+ * - **`AssertionClaims` gains `founderClaimReference`**, optional on the wire and
294
+ * bound to that operation in both directions. A credential scoped to
295
+ * `'claim-founder-wallet'` without it is refused, and so is a credential that
296
+ * carries it without that scope. No credential this surface accepted before is
297
+ * refused now, because until today neither the key nor the scope entry could
298
+ * appear on a credential that verified.
299
+ * - **`Citizenship` gains `'founder-claimed'`** ({@link CitizenshipFounderClaimed}),
300
+ * carrying the wallet and no sign-up grant. A consumer's exhaustive switch on
301
+ * `state` must handle it. The founder claim answers it, and so do both
302
+ * citizenship routes for a claimed founder. A consumer that treated it as
303
+ * `not-provisioned` would offer a claimed founder the provisioning call that
304
+ * must not reach them.
305
+ * - **`CaysoApiErrorCode` gains {@link FounderClaimRefusal} by reference**,
306
+ * including `founder_wallet_lapsed`, which nothing can produce until the lapse
307
+ * is built. It is here from the first version so that it is never a later
308
+ * change to a closed union. It also gains `founder_claim_store_not_configured`,
309
+ * the route's 503 for a wiring with no store, beside its siblings.
310
+ *
311
+ * Under semver below `1.0.0` the minor is where a breaking change goes, so the
312
+ * minor moves and the patch does not.
313
+ *
314
+ * `0.10.0` → `0.11.0` is the build, not the contract (#270). `0.10.0` shipped relative
315
+ * imports without an extension, which Node's ESM loader refuses, so a consumer running
316
+ * the package with no bundler in front of it failed at start-up (piper.platform#182).
317
+ * The package now builds under NodeNext and every emitted specifier names its `.js`
318
+ * file. No type, export, route or file changed, and nothing on the wire moved. By the
319
+ * convention below that is a patch; #270 set the minor, so the minor moves.
320
+ *
321
+ * `0.9.0` → `0.10.0` is the transfer of a restricted lot, decided (CAY-0074). No type
322
+ * changed and nothing on the wire moved. What changed is two cells of
323
+ * `CAPABILITY_POLICY`: `transfer-to-another-holder` for a promotional reward and for
324
+ * a founder allocation went from `open` to `refused`, because a carve does not move
325
+ * restriction and a transfer would shed it. `OPEN_CAPABILITIES` is now empty. The
326
+ * `'open'` standing stays in the union for the next undecided cell.
327
+ *
328
+ * A consumer that does nothing keeps compiling, which would make this a patch. The
329
+ * minor moves instead because the answer a consumer renders changed behind an
330
+ * unchanged shape. A page that showed a citizen "not decided" must now show "not
331
+ * permitted", and that is the case this file exists to make visible.
332
+ *
333
+ * `0.8.0` → `0.9.0` is the published refusal contract (CAY-0058 §5), and it is
334
+ * PURELY ADDITIVE. No existing type changed, no closed union gained a member, no
335
+ * route was added or altered, and no refusal this surface already answered is
336
+ * spelled differently today than it was yesterday. What arrives is the envelope
337
+ * those refusals always travelled in ({@link CaysoErrorResponse}) and the closed
338
+ * set of codes it may carry ({@link CaysoApiErrorCode}), written down at last, plus
339
+ * the one code the request-rate limits answer with.
340
+ *
341
+ * - **`REQUEST_RATE_LIMITED` is new, and so is the refusal behind it.** A request
342
+ * may now be refused because too many arrived too quickly — from one source
343
+ * address, or under one verified credential. A consumer that renders an
344
+ * unrecognised code as an outage would mislead somebody who simply needs to
345
+ * wait, so the code is published and a consumer should render it as a refusal
346
+ * to retry shortly. The refusal carries no header and no body field saying how
347
+ * long shortly is; that is the contract, not an omission.
348
+ * - **`CaysoApiErrorCode` includes `PurchaseFailureReason` and
349
+ * `PurchaseCancelRefusalReason` by reference.** They are not restated, so
350
+ * neither can grow a member the published code set does not carry.
351
+ *
352
+ * A consumer that does nothing keeps working, which under the convention stated
353
+ * below would make this a patch. The minor moves instead because the surface grew a
354
+ * contract a consumer may now depend on exhausting — and because a refusal code that
355
+ * did not exist can now arrive, which is a behaviour change behind unchanged shapes,
356
+ * the case this file exists to make visible.
357
+ *
358
+ * `0.7.0` → `0.8.0` is the sterling that cannot be priced into cents (pen-test
359
+ * C3-3, #148), and it is BREAKING for the same reason the bump below is — a closed
360
+ * union grew:
361
+ *
362
+ * - **`PurchaseFailureReason` gains `'amount_not_priceable'`.** The union is
363
+ * closed and consumers switch on it exhaustively, so a new member is breaking
364
+ * by construction (CAY-0023) — which is the property that makes it safe to
365
+ * add. `POST /api/purchases` accepted any positive whole number of pence and
366
+ * decided whether it could be priced into cents deeper in, where the answer
367
+ * had no way of reaching a consumer; sterling beyond what integer cents can
368
+ * hold at the published value in force is now refused with this member, before
369
+ * anything is authorised, reserved or charged. A consumer asking for ordinary
370
+ * amounts sees no difference; one that could previously be answered with a
371
+ * failure outside the union now gets a member it can render.
372
+ *
373
+ * The bound the refusal marks is arithmetic and not a figure: it is the largest
374
+ * sterling that still prices inside integer cents at the published value, so it
375
+ * rises as the published value ratchets (CAY-0002, CAY-0013) and no number about
376
+ * it appears anywhere on this surface.
377
+ *
378
+ * `0.6.1` → `0.7.0` is the amount-mismatched replay (#134), and it is BREAKING
379
+ * because a closed union grew:
380
+ *
381
+ * - **`PurchaseFailureReason` gains `'amount_mismatch'`.** The union is closed
382
+ * and consumers switch on it exhaustively, so a new member is breaking by
383
+ * construction (CAY-0023) — which is the property that makes it safe to add. A
384
+ * repeat `POST /api/purchases` under a key the same holder has already used at
385
+ * a DIFFERENT `sterlingPence` is now refused with it, where it used to be
386
+ * answered as a Replay at whichever amount the first request carried. Replay
387
+ * means "the same idempotency key again" and a different amount is not the
388
+ * same request; a consumer that resumes an interrupted purchase by repeating
389
+ * it unchanged sees no difference, and one that changed the amount now learns
390
+ * that it must use a new key instead of being quietly charged the old one.
391
+ *
392
+ * `ScopeKey = ContractOperation | InternalOperation` arrived on this same
393
+ * unreleased line and is additive: `ContractOperation` stays closed, so a contract
394
+ * consumer's mistyped operation is still a compile error.
395
+ *
396
+ * `0.6.0` → `0.6.1` is the restricted-Cayso capability policy (CAY-0035), and it
397
+ * is PURELY ADDITIVE. No existing type changed, no closed union gained a member, no
398
+ * route was added or altered, and nothing on the wire moved: `Balance` still reports
399
+ * the same restricted and unrestricted figures it always did. What arrives is a new
400
+ * compile-time table saying what those figures MEAN, which a consumer may read or
401
+ * ignore. A consumer that does nothing keeps working, so the patch moves and the
402
+ * minor does not — the same convention the breaking bumps below state from the other
403
+ * side.
404
+ *
405
+ * It is a version bump at all, rather than none, because the surface genuinely grew:
406
+ * a consumer can now depend on `CAPABILITY_POLICY` existing, and a published package
407
+ * whose exports change without its version changing cannot be depended on at all.
408
+ *
409
+ * `0.5.0` → `0.6.0` is the issued-but-uncaptured purchase (CAY-0033), and it is
410
+ * BREAKING in three places, bumped as one — the same reasoning as the bump below.
411
+ *
412
+ * - **`PurchaseStatus` gains `'issued_uncaptured'`.** The union is closed and
413
+ * consumers switch on it exhaustively, so a new member is breaking by
414
+ * construction (CAY-0023) — which is the property that makes it safe to add. It
415
+ * is NOT terminal: a consumer that treated an unknown status as an ending would
416
+ * stop polling one step before the answer, which is exactly why the new member
417
+ * has to be visible in the version rather than arrive quietly.
418
+ * - **`PurchaseAuthorisationResponse` gains an `'unresolved'` branch.** A repeat
419
+ * `POST` of a key whose purchase has issued but not captured is answered with
420
+ * it. A consumer's exhaustive switch on `outcome` must handle it; there is no
421
+ * live hold to confirm and nothing has ended, so neither existing branch could
422
+ * have carried the truth.
423
+ * - **`PurchaseFailureReason` gains `'capture_failed'`, and
424
+ * `PurchaseCancelRefusalReason` gains `'already_issued'`.** Both unions are
425
+ * closed and exhaustively switched on, so both are breaking additions.
426
+ *
427
+ * `MAX_CAPTURE_ATTEMPTS`, the `PurchaseUnresolved` type and the `LivePurchaseStatus`
428
+ * union are additive and would not have needed a breaking bump on their own. Under
429
+ * semver below `1.0.0` the minor is where a breaking change goes, so the minor moves
430
+ * and the patch does not.
431
+ *
432
+ * `0.4.0` → `0.5.0` is purchase replay and continuation (CAY-0032), and it is
433
+ * BREAKING in three places, bumped as one. It is stated as breaking rather than
434
+ * softened, for the reason the bump below was: a consumer reading this must change
435
+ * what it does.
436
+ *
437
+ * - **`PurchaseAuthorised` gains a required `outcome` discriminant.** The
438
+ * response to `POST /api/purchases` is now ONE declared union
439
+ * ({@link PurchaseAuthorisationResponse}) that a consumer switches on, rather
440
+ * than three shapes it told apart by which fields were present. A consumer
441
+ * that sniffed for `paymentClientSecret` still works by accident today and
442
+ * will not the next time a branch is added, so the discriminant is required
443
+ * and the version says so.
444
+ * - **`PurchaseStatus` gains `'cancelled'`.** The union is closed and consumers
445
+ * switch on it exhaustively, so a new member is breaking by construction
446
+ * (CAY-0023) — which is the property that makes it safe to add. A cancelled
447
+ * purchase is deliberately not a failed one: a failure happened TO somebody, a
448
+ * cancellation was CHOSEN, and rendering them alike tells a holder their
449
+ * payment failed when they changed their mind.
450
+ * - **`ContractOperation` gains `'cancel-purchase'`.** An issuer minting
451
+ * assertions must put it in `scope` for a holder to be able to cancel, and an
452
+ * empty or unchanged scope authorises nothing (CAY-0030). A consumer that does
453
+ * not mint it simply cannot cancel — which is a refusal, not a failure, but it
454
+ * is a change to what an issuer must do.
455
+ *
456
+ * The cancel route, the terminal-status statement, the reservation window and the
457
+ * cancel response types are additive and would not have needed a breaking bump on
458
+ * their own. Under semver below `1.0.0` the minor is where a breaking change goes,
459
+ * so the minor moves and the patch does not.
460
+ *
461
+ * `0.3.0` → `0.4.0` was citizenship provisioning (CAY-0031), and it was a BREAKING
462
+ * change in two places, bumped as one. Both are stated as breaking rather than
463
+ * softened: a consumer reading this must change what it does, and a version that
464
+ * implied otherwise would be the lie that costs it an outage.
465
+ *
466
+ * - **`GET /api/wallet` no longer provisions.** It used to create a wallet on
467
+ * the first authenticated read (CAY-0022); it now creates nothing and refuses
468
+ * an unprovisioned citizen with {@link NOT_PROVISIONED}. A consumer that
469
+ * relied on reading a wallet to bring one into being must call
470
+ * `ROUTES.citizenshipProvision` first. Nothing in a type changed, which is
471
+ * exactly why the version has to say so: a silent behaviour change behind an
472
+ * unchanged shape is the worst kind, and the only place a consumer can be
473
+ * warned is here.
474
+ * - **`PurchaseFailureReason` gains `'not_provisioned'`.** The union is closed
475
+ * and consumers switch on it exhaustively, so a new member is breaking by
476
+ * construction (CAY-0023) — which is the property that makes it safe to add.
477
+ *
478
+ * The new `citizenship` types and the two new routes are additive and would not
479
+ * have needed a breaking bump on their own. Under semver below `1.0.0` the minor
480
+ * is where a breaking change goes, so the minor moves and the patch does not.
481
+ */
482
+ export declare const CONTRACT_VERSION: "0.23.0";
483
+ /** The package's own name, so a consumer can name what it depends on. */
484
+ export declare const packageName = "@percayso-community/cayso-contracts";
485
+ /**
486
+ * The `cayso.wallet` capability name (slice 5). A value, not a type: a consumer
487
+ * names the capability it is reading, and `CaysoWallet.capability` is typed as
488
+ * `typeof WALLET_CAPABILITY` so the two can never drift apart.
489
+ */
490
+ export { WALLET_CAPABILITY } from './wallet.js';
491
+ /**
492
+ * The `cayso.purchase` capability name and the route table (slice 6). Both are
493
+ * values: a consumer names the capability it is exercising, and reads a method
494
+ * and path from `ROUTES` rather than hand-writing a URL. The closed
495
+ * failure-reason union that pairs with them is a type, exported below.
496
+ */
497
+ export { PURCHASE_CAPABILITY } from './purchase.js';
498
+ export { ROUTES } from './routes.js';
499
+ /**
500
+ * The purchase lifecycle's runtime half (CAY-0032): which statuses a purchase
501
+ * never leaves, the predicate over them, and the window an authorisation holds its
502
+ * reserved headroom for.
503
+ *
504
+ * Values rather than types, and for the same reason the credential's clock
505
+ * parameters are: a consumer has to be able to READ them. A poller deciding
506
+ * whether to stop needs the terminal set at runtime, and a confirmation page
507
+ * deciding how long to stay live needs the window — neither can be read from a
508
+ * type, and a consumer that maintains its own copy of either maintains the copy
509
+ * that goes stale. The window is a MECHANISM parameter of this contract, the
510
+ * documented exception to keeping numbers in the canon PRD; no economic figure is
511
+ * here.
512
+ */
513
+ export { TERMINAL_PURCHASE_STATUSES, isTerminalPurchaseStatus, PURCHASE_RESERVATION_WINDOW_SECONDS, } from './purchase.js';
514
+ /**
515
+ * How many capture attempts a purchase gets before only an operator can move it
516
+ * (CAY-0033). A value for the same reason the window beside it is one: a consumer
517
+ * watching a purchase sit in `'issued_uncaptured'` is entitled to know that the
518
+ * retrying is bounded and where the bound is, and cannot read either from a type.
519
+ * A MECHANISM parameter of this contract, not an economic figure.
520
+ */
521
+ export { MAX_CAPTURE_ATTEMPTS } from './purchase.js';
522
+ /**
523
+ * The `not_provisioned` wire code (CAY-0031). A value, not a type: a consumer
524
+ * comparing a refusal against the contract's own string is comparing against one
525
+ * source, where a consumer retyping our spelling has made a second.
526
+ */
527
+ export { NOT_PROVISIONED } from './citizenship.js';
528
+ /**
529
+ * The credential's clock and retention parameters (CAY-0030): the ceiling an
530
+ * `exp` is measured against, the skew two honest clocks are allowed, and the
531
+ * floor on how long a recorded use must be kept so replay is actually refused.
532
+ *
533
+ * Values rather than types because a consumer has to be able to READ them — an
534
+ * issuer sizing its lifetimes against our ceiling cannot do it from a type — and
535
+ * because the retention floor is DERIVED from the other two and must stay derived.
536
+ * They are security parameters of this credential, which is the documented
537
+ * exception to keeping numbers in the canon PRD; no economic figure is here.
538
+ */
539
+ export { MAX_ASSERTION_LIFETIME_SECONDS, CLOCK_SKEW_TOLERANCE_SECONDS, MINIMUM_ASSERTION_USE_RETENTION_SECONDS, } from './assertion.js';
540
+ /**
541
+ * The assurance profile (CAY-0029): what each `VerificationMethod` asserts, which
542
+ * methods each operation accepts, and the version a claim is minted under.
543
+ *
544
+ * Unlike the other contracts here, this one has a RUNTIME half and must: a
545
+ * statement of evidence that only existed as a type would be erased before any
546
+ * issuer could check its own claim against it, and an acceptance policy only a
547
+ * compiler can read is not a policy a consumer can read. The values are frozen
548
+ * data and pure functions — nothing runs on import.
549
+ */
550
+ export { ASSURANCE_PROFILE_VERSION, RECOGNISED_ASSURANCE_PROFILE_VERSIONS, EVIDENCE_STATEMENTS, VERIFICATION_METHODS, ASSURANCE_POLICY, CONTRACT_OPERATIONS, OPERATION_FOR_ROUTE, acceptedMethods, assessAssurance, evidenceSupports, methodForEvidence, } from './assurance.js';
551
+ /**
552
+ * The restricted-Cayso capability policy (CAY-0035): what each kind of holding may
553
+ * do, which kinds land restricted and what an expiry does for each, and where a
554
+ * lot of any kind stands once its restriction has lapsed.
555
+ *
556
+ * Values rather than types for the same reason the assurance policy is one — a
557
+ * table only a compiler can read is not a table a consumer can render. A wallet
558
+ * page showing a holder why part of their balance cannot be cashed out yet reads
559
+ * these; a page that hard-coded the answer would be a second copy of a policy that
560
+ * has one home. Frozen data and nothing else: there is deliberately no function
561
+ * here, because a predicate over a standing would have to fold an open cell into
562
+ * a yes or a no.
563
+ *
564
+ * `OPEN_CAPABILITIES` is exported so that "which cells has nobody decided" has a
565
+ * runtime answer. It is empty since CAY-0074 settled the two transfer cells; a
566
+ * consumer still renders any cell it lists as open, never as refused, which is the
567
+ * comfortable mistake.
568
+ */
569
+ export { CAPABILITY_POLICY, RESTRICTION_ON_ARRIVAL, ONCE_UNRESTRICTED, HOLDING_KINDS, HOLDING_CAPABILITIES, OPEN_CAPABILITIES, } from './restriction.js';
570
+ /**
571
+ * The money path's own cents type (CAY-0045): the constructor that is the only way
572
+ * to obtain a {@link PositiveCents}, the amount a caller may ask the economy to
573
+ * move.
574
+ *
575
+ * A value rather than a type, and it has to be: a brand is erased, so a type alone
576
+ * publishes a shape nobody can construct. It is the second layer CLAUDE.md requires
577
+ * beside the schema's `CHECK (cents > 0)`, and it is HERE rather than beside the
578
+ * carve because `packages/ledger` may not depend on an app — the module that moves
579
+ * cents could not otherwise reach the module that types them (pen-test C3-1).
580
+ *
581
+ * It changes no wire shape. `Cents` stays the permissive alias every request and
582
+ * response speaks in, the served contract schema is unchanged, and nothing on this
583
+ * surface newly refuses a figure a consumer could already send. `money.ts` says why
584
+ * the two types are separate on purpose.
585
+ */
586
+ export { positiveCents } from './money.js';
587
+ /**
588
+ * The refusal envelope's one published code (CAY-0058 §5): what a request refused
589
+ * by a request-rate limit answers with.
590
+ *
591
+ * A value rather than a type for the reason `NOT_PROVISIONED` is one — a consumer
592
+ * comparing a refusal against a string it retyped itself is a consumer whose
593
+ * rendering goes wrong silently. The envelope and the closed code union beside it
594
+ * are erased and appear in the type block below; this constant is the whole of the
595
+ * runtime surface the refusal contract adds.
596
+ */
597
+ export { REQUEST_RATE_LIMITED } from './errors.js';
598
+ /**
599
+ * The marketplace receipt's runtime half (CAY-0083 §1): the algorithm it is signed
600
+ * with, and the exact bytes the signature is over.
601
+ *
602
+ * Values rather than types because both sides must compute the same bytes: a
603
+ * verifier that wrote its own JSON for the statement would one day disagree with the
604
+ * signer by a space and refuse every receipt. The encoder is pure — JSON and a UTF-8
605
+ * encoder, no cryptographic dependency — and refuses a statement that is not exactly
606
+ * one of the four.
607
+ */
608
+ export { MARKETPLACE_RECEIPT_SIGNATURE_ALGORITHM, encodeMarketplaceReceiptStatement, } from './marketplace-receipt.js';
609
+ export type { PositiveCents } from './money.js';
610
+ export type { CaysoApiErrorCode, CaysoErrorResponse } from './errors.js';
611
+ export type { HolderType, Millis, Cents, WalletRecord, Balance, Allowance, WalletView, CaysoWallet, } from './wallet.js';
612
+ export type { SignUpGrantTerms, SignUpGrant, CitizenshipNotProvisioned, CitizenshipProvisioned, CitizenshipFounderClaimed, Citizenship, CitizenshipView, FounderClaimRefusal, } from './citizenship.js';
613
+ export type { OrganisationView } from './organisation.js';
614
+ export type { CommercialPaymentAuthority, CommercialPaymentRequest, CommercialPayment, CommercialPaymentMade, CommercialPaymentRefused, CommercialPaymentResponse, CommercialPaymentRefusal, } from './commercial-payment.js';
615
+ export type { QuoteSide, QuoteRequest, Quote, QuotePlaced, QuoteRefused, QuoteResponse, QuoteEntryRefusal, QuotePlacementRefusal, QuoteWithdrawalRequest, QuoteWithdrawal, QuoteWithdrawn, QuoteWithdrawalRefused, QuoteWithdrawalResponse, QuoteWithdrawalRefusal, BuyBackRequest, BuyBack, BuyBackMade, BuyBackRefused, BuyBackResponse, BuyBackRefusal, BookLevel, QuoteStatus, QuoteWithdrawalReason, OwnQuote, OwnQuoteNotWithdrawn, OwnQuoteWithdrawn, CitizenMarketView, CitizenMarketViewed, CitizenMarketViewRefusal, CitizenMarketViewRefused, CitizenMarketResponse, } from './citizen-market.js';
616
+ export type { MarketplaceReceiptSignatureAlgorithm, MarketplaceReceiptKeyId, MarketplaceSaleKind, MarketplaceReceiptLeg, MarketplaceSettlementReceiptStatement, HousePublisherChargeReceiptStatement, ThirdPartyRefundReceiptStatement, HousePublisherRefundReceiptStatement, MarketplaceReceiptStatement, MarketplaceReceipt, MarketplaceReceiptReadRequest, MarketplaceReceiptFound, MarketplaceNoMovement, MarketplaceReceiptReadRefusal, MarketplaceReceiptReadRefused, MarketplaceReceiptReadResponse, } from './marketplace-receipt.js';
617
+ export type { StoreSignedStatement, MarketplaceOrderRequest, MarketplaceRefundRequest, MarketplaceOrderReceipt, MarketplaceRefundReceipt, MarketplaceOrderSettled, MarketplaceOrderRefused, MarketplaceOrderResponse, MarketplaceOrderRefusal, MarketplaceRefundSettled, MarketplaceRefundRefused, MarketplaceRefundResponse, MarketplaceRefundRefusal, } from './marketplace-settlement.js';
618
+ export type { PurchaseRequest, PurchaseAuthorised, PurchaseTerminal, PurchaseUnresolved, PurchaseRefused, PurchaseAuthorisationResponse, PurchaseFailureReason, PurchaseStatus, LivePurchaseStatus, TerminalPurchaseStatus, PurchaseCancelRefusalReason, PurchaseCancelled, PurchaseCancelRefused, PurchaseCancelResponse, PurchaseResult, } from './purchase.js';
619
+ export type { VerificationMethod, VerificationStatus, SubjectPersonhood, AssertionClaims, AssertionHeader, AssertionEnvelope, ContractOperation, InternalOperation, ScopeKey, } from './assertion.js';
620
+ export type { VerificationEvidence, EvidenceStatement, MethodDecision, MethodDecisions, AssuranceRequired, AssuranceNotRequired, OperationAssurance, AssuranceRefusalReason, AssuranceAssessment, } from './assurance.js';
621
+ export type { Restriction, HoldingKind, HoldingCapability, PermittedStanding, RefusedStanding, OpenStanding, CapabilityStanding, CapabilityCell, CapabilityCoordinate, CapabilityPolicy, ArrivalAndExpiry, } from './restriction.js';