@percayso-community/cayso-contracts 0.23.0 → 0.26.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.
package/README.md CHANGED
@@ -12,26 +12,45 @@ literal `0` to `number` — so the one structural guarantee in that surface dies
12
12
  the HTTP boundary. The fix is a single published package whose types a consumer
13
13
  imports rather than retypes.
14
14
 
15
- ## The Piper-facing surface only
16
-
17
- Published here: the record and response types, the closed failure-reason union,
18
- the assertion claims and the route constants — the surface Piper reads.
19
-
20
- **Deliberately not published:** peer types, admin types, holdings and carves.
21
- They are not a consumer's business, and putting them on the public surface widens
22
- it for nothing.
15
+ ## The surface of every consumer outside this tree
16
+
17
+ Published here: the record and response types, the closed failure-reason unions,
18
+ the assertion claims and the route constants — the surface every consumer outside
19
+ this repository reads (CAY-0026, Amendment 3). Piper is the first consumer. The
20
+ Percayso Cloud is the second: its Contribution Store presents the settlement
21
+ assertion to Cayso directly, and the Cloud generates its types from the `schema`
22
+ entry point rather than typing Cayso's half by hand. The Cloud's two seams live in
23
+ `cloud-settlement`, and the settlement path, which a registered issuer calls and
24
+ no person does, is `CLOUD_SETTLEMENT_ROUTE`, published apart from `ROUTES`.
25
+
26
+ **The operator read surface, on its own entry point** (CAY-0026, Amendment 4). Three
27
+ reads an operator app's *server* calls — the movement list, the purchase list and the
28
+ quickening ladder — are published at `@percayso-community/cayso-contracts/operator`:
29
+ their paths and scopes, query inputs (wallet id, a half-open `[from, to)` window, a
30
+ keyset cursor), rows and pages, and their closed refusal and not-configured bodies.
31
+ Money is `Cents`, a wallet is named by its wallet id, and no Percayso identity
32
+ appears on any row. It is not re-exported from the barrel, so Piper and the Cloud
33
+ never import an operator vocabulary by accident, and the schema describes it under
34
+ its own `operator` key rather than among the person-facing types. Cayso sends no
35
+ CORS headers: these reads are for a server, never a browser. Widening the entry
36
+ point beyond these three needs a further amendment.
37
+
38
+ **Deliberately not published:** peer types, holdings and carves, and every operator
39
+ route but those three reads. They are not a consumer's business, and putting them on
40
+ the public surface widens it for nothing.
23
41
 
24
42
  **This package carries no numbers.** Amounts, rates, tiers, schedules and
25
43
  thresholds live in the canon PRD and are read from one place. None of them are
26
44
  restated here.
27
45
 
28
- ## Three entry points
46
+ ## Four entry points
29
47
 
30
48
  | Import | What it gives you |
31
49
  |---|---|
32
50
  | `@percayso-community/cayso-contracts` | Types and constants. No runtime. |
33
51
  | `@percayso-community/cayso-contracts/client` | The thin client — fetch, assertion header, idempotent retry. |
34
52
  | `@percayso-community/cayso-contracts/schema` | A machine-readable descriptor of the published surface. |
53
+ | `@percayso-community/cayso-contracts/operator` | The three operator reads' types and route constants, for an operator app's server. |
35
54
 
36
55
  The split is the point: a consumer wanting only the types takes on no runtime at
37
56
  all. The client owns the fetch, the assertion header and the idempotent retry.
@@ -63,9 +82,14 @@ describes. The thin client's `getVersion()` reads it and warns once, per client
63
82
  instance, when the server's contract *major* differs from the one the client was
64
83
  built against.
65
84
 
85
+ After a minor bump that is additive on the wire, a deployment keeps the previous
86
+ minor in `supportedContractVersions` for one release, so a consumer still pinned
87
+ to it keeps working while it moves. A breaking bump drops it, and says so in the
88
+ bump's changelog.
89
+
66
90
  Alongside it, `GET /api/version/schema` serves the same machine-readable
67
- descriptor as `@percayso-community/cayso-contracts/schema` — the Piper-facing surface only, with no
68
- operator, webhook or peer route. It exists for tooling and diagnostics.
91
+ descriptor as `@percayso-community/cayso-contracts/schema` — the surface outside consumers read, with
92
+ no operator, webhook or peer route. It exists for tooling and diagnostics.
69
93
 
70
94
  **It is not a substitute for depending on this package.** The descriptor is
71
95
  data; the guarantee is the *types*, and the types do not exist at runtime — they
@@ -353,15 +353,27 @@
353
353
  * checked. Neither is a second use of `'authorise-purchase'`, which brings sterling
354
354
  * in, or of `'make-commercial-payment'`, which is organisation-to-Citizen only.
355
355
  * Both are classified before they are served, and no route serves either yet.
356
+ *
357
+ * `'present-standing-authorisation'` is an owner delegating spending to their
358
+ * Instance on Percayso Cloud services (CMTY-0018 §1): the Instance presents the
359
+ * owner's standing authorisation, signed by the Instance key, under the owner's
360
+ * assertion, and Cayso answers with an acknowledgement the Cloud meters against.
361
+ * It is not a second use of `'make-commercial-payment'`: nothing moves when it is
362
+ * presented, and what it authorises is spending in later periods, settled by the
363
+ * Contribution Store's assertion, which no person presents and which therefore has
364
+ * no operation here. It is classified before it is served.
356
365
  */
357
- export type ContractOperation = 'read-own-wallet' | 'read-purchase-result' | 'authorise-purchase' | 'cancel-purchase' | 'provision-citizenship' | 'read-own-citizenship' | 'provision-organisation' | 'claim-founder-wallet' | 'make-commercial-payment' | 'place-quote' | 'withdraw-quote' | 'request-buy-back' | 'read-citizen-market' | 'read-marketplace-receipt' | 'settle-marketplace-order' | 'settle-marketplace-refund';
366
+ export type ContractOperation = 'read-own-wallet' | 'read-purchase-result' | 'authorise-purchase' | 'cancel-purchase' | 'provision-citizenship' | 'read-own-citizenship' | 'provision-organisation' | 'claim-founder-wallet' | 'make-commercial-payment' | 'place-quote' | 'withdraw-quote' | 'request-buy-back' | 'read-citizen-market' | 'read-marketplace-receipt' | 'settle-marketplace-order' | 'settle-marketplace-refund' | 'present-standing-authorisation';
358
367
  /**
359
368
  * An operation key belonging to a deployment's OWN surfaces rather than to this
360
369
  * contract — operator work, above all. Deliberately not enumerated: this package
361
370
  * is published and carries the Piper-facing surface only (CAY-0026), and naming
362
371
  * an internal vocabulary here would publish a set of keys no consumer of this
363
372
  * contract may ever present. Where the closed set is kept instead is stated on
364
- * {@link ScopeKey}.
373
+ * {@link ScopeKey}. The three operator READ scopes are published, but on the
374
+ * `./operator` entry point (`OperatorReadScope`, CAY-0026 Amendment 4), for an
375
+ * operator app's server and not for this contract's consumers — so this type
376
+ * stays open, and the rest of the operator vocabulary stays unpublished.
365
377
  */
366
378
  export type InternalOperation = string;
367
379
  /**
package/dist/assurance.js CHANGED
@@ -452,6 +452,27 @@ export const ASSURANCE_POLICY = {
452
452
  "Platform's signed refund decision; the assertion shows the buyer is present, and it is held " +
453
453
  'to the same bar as the sale it refunds.',
454
454
  },
455
+ // An owner delegating spending to their Instance (CMTY-0018 §1). Money-grade, in
456
+ // the pattern of the commercial payment: what is authorised is cents leaving the
457
+ // holder's wallet in every later period, up to a cap, without the holder present.
458
+ // The passkey ceremony is the assertion's verification method, and the bar is
459
+ // the purchase path's, so a bar no issuer can yet clear does not shut the Cloud
460
+ // on every deployment. What limits the spending is the cap and its canon ceiling,
461
+ // and neither is an assurance question.
462
+ 'present-standing-authorisation': {
463
+ operation: 'present-standing-authorisation',
464
+ assurance: 'required',
465
+ decisions: {
466
+ // Asserts nothing; permanently refused wherever "identity-verified" is meant.
467
+ 'dev-bypass': 'refused',
468
+ document: 'accepted',
469
+ 'document-and-biometric': 'accepted',
470
+ },
471
+ rationale: "Presenting a standing authorisation delegates spending from the holder's wallet to their " +
472
+ 'Instance, up to a cap in every period, so it is money-grade: anything but the development ' +
473
+ 'bypass. Nothing moves when it is presented; what it authorises moves later, without the ' +
474
+ 'holder present, which is why the bar is applied here.',
475
+ },
455
476
  };
456
477
  /**
457
478
  * Every operation, as a value. Derived from {@link ASSURANCE_POLICY} for the same
@@ -488,6 +509,8 @@ export const OPERATION_FOR_ROUTE = {
488
509
  placeQuote: 'place-quote',
489
510
  withdrawQuote: 'withdraw-quote',
490
511
  requestBuyBack: 'request-buy-back',
512
+ marketplaceOrder: 'settle-marketplace-order',
513
+ standingAuthorisation: 'present-standing-authorisation',
491
514
  version: null,
492
515
  };
493
516
  /**
package/dist/client.d.ts CHANGED
@@ -69,7 +69,9 @@
69
69
  */
70
70
  import type { BuyBackMade, BuyBackRequest, CitizenMarketViewed, QuotePlaced, QuoteRequest, QuoteWithdrawalRequest, QuoteWithdrawn } from './citizen-market.js';
71
71
  import type { CitizenshipFounderClaimed, CitizenshipView } from './citizenship.js';
72
+ import type { StandingAuthorisationAcknowledged, StandingAuthorisationRequest } from './cloud-settlement.js';
72
73
  import type { CommercialPaymentMade, CommercialPaymentRequest } from './commercial-payment.js';
74
+ import type { MarketplaceOrderRequest, MarketplaceOrderSettled } from './marketplace-settlement.js';
73
75
  import type { OrganisationView } from './organisation.js';
74
76
  import type { PurchaseAuthorised, PurchaseCancelled, PurchaseRequest, PurchaseResult, PurchaseTerminal } from './purchase.js';
75
77
  import type { WalletView } from './wallet.js';
@@ -251,6 +253,30 @@ export interface CaysoClient {
251
253
  * and means nothing moved and nothing is paid.
252
254
  */
253
255
  requestBuyBack(req: BuyBackRequest): Promise<BuyBackMade>;
256
+ /**
257
+ * Present Store Platform's signed order to settle a house-publisher marketplace sale
258
+ * under the buyer's assertion (`settle-marketplace-order`, CAY-0082 §2, CAY-0083 §3),
259
+ * and receive Cayso's signed receipt — or REPLAY a sale already settled.
260
+ *
261
+ * Safe to repeat with no key of its own: the idempotency key is inside the signed
262
+ * order, and presenting the same order again answers the receipt already written
263
+ * (CAY-0082 §4). A refusal arrives as a thrown {@link CaysoApiError} whose `code` is
264
+ * a `MarketplaceOrderRefusal` member, one of the gate's codes, or a seam code, and
265
+ * means nothing moved.
266
+ */
267
+ settleMarketplaceOrder(req: MarketplaceOrderRequest): Promise<MarketplaceOrderSettled>;
268
+ /**
269
+ * Present the owner's standing authorisation, signed by the Instance key, under the
270
+ * owner's assertion (`present-standing-authorisation`, CMTY-0018 §1), and receive
271
+ * Cayso's signed acknowledgement for the Percayso Cloud.
272
+ *
273
+ * Safe to repeat: the authorisation's `jti` is its own key, and presenting the same
274
+ * authorisation again binds nothing twice. A refusal arrives as a thrown
275
+ * {@link CaysoApiError} whose `code` is a `StandingAuthorisationRefusal` member, one
276
+ * of the gate's codes, or a seam code, and means nothing was bound. Published before
277
+ * the route is served.
278
+ */
279
+ presentStandingAuthorisation(req: StandingAuthorisationRequest): Promise<StandingAuthorisationAcknowledged>;
254
280
  getVersion(): Promise<CaysoVersion>;
255
281
  }
256
282
  /**
package/dist/client.js CHANGED
@@ -260,6 +260,26 @@ function buildClient(options, internals) {
260
260
  idempotencyKey: req.idempotencyKey,
261
261
  });
262
262
  },
263
+ async settleMarketplaceOrder(req) {
264
+ return requestJson({
265
+ method: ROUTES.marketplaceOrder.method,
266
+ path: ROUTES.marketplaceOrder.path,
267
+ // Safe to repeat: the key is inside the signed order, and the same order
268
+ // presented again answers the receipt already written, never a second sale.
269
+ idempotent: true,
270
+ body: req,
271
+ });
272
+ },
273
+ async presentStandingAuthorisation(req) {
274
+ return requestJson({
275
+ method: ROUTES.standingAuthorisation.method,
276
+ path: ROUTES.standingAuthorisation.path,
277
+ // Safe to repeat: the authorisation's `jti` is its key, and the same
278
+ // authorisation presented again binds nothing twice.
279
+ idempotent: true,
280
+ body: req,
281
+ });
282
+ },
263
283
  async getPurchase(purchaseId) {
264
284
  return requestJson({
265
285
  method: ROUTES.purchaseResult.method,