@percayso-community/cayso-contracts 0.24.0 → 0.27.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 +35 -11
- package/dist/assertion.d.ts +21 -2
- package/dist/assurance.js +41 -0
- package/dist/citizen-transfer.d.ts +110 -0
- package/dist/citizen-transfer.js +16 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.js +20 -0
- package/dist/cloud-settlement.d.ts +460 -0
- package/dist/cloud-settlement.js +16 -0
- package/dist/contract-schema.generated.d.ts +2 -1
- package/dist/contract-schema.generated.js +1995 -32
- package/dist/errors.d.ts +10 -2
- package/dist/index.d.ts +48 -3
- package/dist/index.js +46 -3
- package/dist/operator.d.ts +298 -0
- package/dist/operator.js +48 -0
- package/dist/routes.d.ts +48 -0
- package/dist/routes.js +42 -0
- package/dist/schema-types.d.ts +48 -6
- package/dist/schema.d.ts +1 -1
- package/package.json +6 -2
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `cloud-settlement` — the Percayso Cloud's two seams with Cayso: the **standing
|
|
3
|
+
* authorisation** an Instance presents and Cayso acknowledges, and the **settlement
|
|
4
|
+
* assertion** the Contribution Store signs once per period and Cayso fails closed
|
|
5
|
+
* on (CMTY-0018, as Cayso amended it on 5 October 2026).
|
|
6
|
+
*
|
|
7
|
+
* **This is the contract surface only.** Nothing here is served, settled or
|
|
8
|
+
* stored: no route answers either seam yet, no movement kind exists for either
|
|
9
|
+
* leg, and nothing binds a Node or an Instance key to a wallet. Those are later
|
|
10
|
+
* slices. What is published is what the Cloud generates its own types from
|
|
11
|
+
* (CMTY-0018 §3), so that neither side redeclares the other's half.
|
|
12
|
+
*
|
|
13
|
+
* ## Two seams, two authorities
|
|
14
|
+
*
|
|
15
|
+
* **The standing authorisation** is an owner delegating spending: one signed act,
|
|
16
|
+
* on a passkey ceremony, allowing their Instance to spend up to a cap per
|
|
17
|
+
* settlement period on Percayso Cloud services. The Instance presents it under the
|
|
18
|
+
* owner's assertion (`present-standing-authorisation`, `ROUTES.standingAuthorisation`),
|
|
19
|
+
* which is money-grade in `ASSURANCE_POLICY`, so `dev-bypass` is never admissible.
|
|
20
|
+
* Cayso answers with an {@link AuthorisationAcknowledgementClaims}, signed by a
|
|
21
|
+
* Cayso issuer key, which the Instance hands to the Cloud. An Instance mediates and
|
|
22
|
+
* does not vouch (CAY-0057): the acknowledgement is how Cayso vouches for an
|
|
23
|
+
* Instance key the Cloud has never seen, without the Cloud learning whose it is.
|
|
24
|
+
*
|
|
25
|
+
* **The settlement assertion** is the Contribution Store's statement of one
|
|
26
|
+
* period: contribution by Node, consumption by authorisation. It is presented by
|
|
27
|
+
* the Store directly, authenticated by a registered Store issuer (CAY-0030) and
|
|
28
|
+
* not by a person, so its path is {@link CLOUD_SETTLEMENT_ROUTE} and never an entry
|
|
29
|
+
* in `ROUTES`, whose every entry is classified by a person's assurance.
|
|
30
|
+
*
|
|
31
|
+
* Both documents and the acknowledgement are compact assertions in CAY-0072's
|
|
32
|
+
* format: three unpadded base64url segments, a header of exactly `alg` and `kid`,
|
|
33
|
+
* the signature over the bytes that travelled, and `iat` and `exp` in **seconds**.
|
|
34
|
+
* This module types the claims; the request carries the compact string exactly as
|
|
35
|
+
* signed, and Cayso reads nothing from it as a fact until it has verified it.
|
|
36
|
+
*
|
|
37
|
+
* ## Where this departs from CMTY-0018: no Instance ID crosses
|
|
38
|
+
*
|
|
39
|
+
* CMTY-0018 puts an Instance ID in all three documents. **Cayso records no
|
|
40
|
+
* Instance ID in any role** (CAY-0059 §6), and the pillar owner kept that rule
|
|
41
|
+
* unamended on 5 October 2026. So the spender is identified by two things that
|
|
42
|
+
* already exist and say nothing about where an Instance runs:
|
|
43
|
+
*
|
|
44
|
+
* - the **authorisation's `jti`**, unique per authorisation, which every
|
|
45
|
+
* consumption row cites; and
|
|
46
|
+
* - the **Instance key's `kid`** ({@link InstanceKeyId}), a pseudonymous key id.
|
|
47
|
+
*
|
|
48
|
+
* A {@link StandingAuthorisationClaims}' `iss` and `sub` are that `kid`; the
|
|
49
|
+
* acknowledgement carries the authorisation's `jti` and the `kid`; a consumption
|
|
50
|
+
* row is keyed by the authorisation's `jti` alone. The Cloud still meters by
|
|
51
|
+
* Instance ID on its own side, and that never crosses to Cayso. CMTY-0018 is a
|
|
52
|
+
* Community record, so the change is Cayso's to request rather than to make: an
|
|
53
|
+
* amendment request goes to community.documentation, and until it lands this
|
|
54
|
+
* package, not the record, is the shape the Cloud generates from (CAY-0026,
|
|
55
|
+
* Amendment 3).
|
|
56
|
+
*
|
|
57
|
+
* ## Fail closed on the whole assertion
|
|
58
|
+
*
|
|
59
|
+
* A settlement assertion is settled whole or not at all (CAY-0021, CMTY-0018 §2).
|
|
60
|
+
* A refused one is a dispute between the two pillars, raised to a person: never
|
|
61
|
+
* partially settled, never silently corrected on either side. The refusal names
|
|
62
|
+
* the first reason, and, when the reason is about a row, which row
|
|
63
|
+
* ({@link ContributionRowRefused}, {@link ConsumptionRowRefused}). "First" is a
|
|
64
|
+
* fixed order: the assertion as a whole, then the contribution leg in the order
|
|
65
|
+
* it was signed, then the consumption leg in the order it was signed.
|
|
66
|
+
*
|
|
67
|
+
* The same assertion presented twice is a no-op (CAY-0023): its `jti` is the
|
|
68
|
+
* period's id and the idempotency key, and a replay answers what the first
|
|
69
|
+
* presentation answered.
|
|
70
|
+
*
|
|
71
|
+
* ## What is not here
|
|
72
|
+
*
|
|
73
|
+
* - **No Instance ID**, in any claim, row, request, answer or refusal (CAY-0059 §6).
|
|
74
|
+
* - **No wallet, account or Citizen** in anything Cayso signs for the Cloud, nor
|
|
75
|
+
* in anything the Store signs for Cayso. Cayso resolves a Node and a key to a
|
|
76
|
+
* wallet on its own side, in the Trust Network (CAY-0006).
|
|
77
|
+
* - **No Percayso identity** (CAY-0006). The owner's assertion authenticates the
|
|
78
|
+
* presentation; its subject is never a claim here.
|
|
79
|
+
* - **No figure.** The cap's ceiling, the authorisation's longest life, the
|
|
80
|
+
* period's length and rule, and every rate are canon figures read from one
|
|
81
|
+
* place. `period` is an opaque identifier; this package sets no value for it.
|
|
82
|
+
* - **No unconfigured adapter in either union.** A seam this deployment has not
|
|
83
|
+
* been told about — no Store issuer registered, no Cayso acknowledgement key, no
|
|
84
|
+
* ceiling configured — is a `503` in the refusal envelope's own code, spelled by
|
|
85
|
+
* the slice that serves the route, never a member here.
|
|
86
|
+
* - **No movement kind.** CMTY-0018 §2 proposes one per leg (CAY-0082's
|
|
87
|
+
* pattern). The reasons a movement can be refused for — a short wallet, a
|
|
88
|
+
* contended carve — arrive with the slice that designs those kinds, as a new
|
|
89
|
+
* contract version.
|
|
90
|
+
* - **No chain height.** A period is bounded in UTC seconds until there is a chain
|
|
91
|
+
* to read (CAY-0016); the height a Store read is a later version's member.
|
|
92
|
+
*/
|
|
93
|
+
import type { Cents } from './wallet.js';
|
|
94
|
+
/**
|
|
95
|
+
* The id of one Instance key: the RFC 7638 SHA-256 thumbprint of its public half,
|
|
96
|
+
* unpadded base64url. Derived rather than minted, so a key id cannot be re-pointed
|
|
97
|
+
* at a different key, and pseudonymous, so it says nothing about where the
|
|
98
|
+
* Instance runs (CAY-0059 §6). Opaque to a consumer: compare it, never parse it.
|
|
99
|
+
*/
|
|
100
|
+
export type InstanceKeyId = string;
|
|
101
|
+
/**
|
|
102
|
+
* Which period rule a cap is per: an opaque identifier of the rule Cayso publishes.
|
|
103
|
+
* Its value, and the rule's length, are the canon's and are not set here
|
|
104
|
+
* (CMTY-0018 §1, community.documentation#24).
|
|
105
|
+
*/
|
|
106
|
+
export type SettlementPeriodRule = string;
|
|
107
|
+
/** One settlement period's id, made by the period rule. Opaque here. */
|
|
108
|
+
export type SettlementPeriodId = string;
|
|
109
|
+
/** A Node's id, as the Cloud's Node Registry holds it. Never an account. */
|
|
110
|
+
export type NodeId = string;
|
|
111
|
+
/**
|
|
112
|
+
* The Contribution Store's issuer id, one per environment, so an assertion signed
|
|
113
|
+
* for one environment can never settle on another's ledger (CMTY-0018 §2). Closed:
|
|
114
|
+
* an environment this union does not name is not one the Store signs for.
|
|
115
|
+
*/
|
|
116
|
+
export type ContributionStoreIssuer = 'percayso-cloud-store:dev' | 'percayso-cloud-store:stage' | 'percayso-cloud-store:main';
|
|
117
|
+
/** The audience of a standing authorisation and of its acknowledgement. */
|
|
118
|
+
export type PercaysoCloudAudience = 'percayso-cloud';
|
|
119
|
+
/**
|
|
120
|
+
* The owner's act: one signed authorisation, made in their Instance on a passkey
|
|
121
|
+
* ceremony, allowing that Instance to spend up to `cap_cents` per settlement
|
|
122
|
+
* period on Percayso Cloud services (CMTY-0018 §1). Signed by the Instance key, in
|
|
123
|
+
* CAY-0072's format, whose header `kid` is `iss`.
|
|
124
|
+
*/
|
|
125
|
+
export interface StandingAuthorisationClaims {
|
|
126
|
+
/** The Instance key that signed it. The same value as `sub` and the header's `kid`. */
|
|
127
|
+
readonly iss: InstanceKeyId;
|
|
128
|
+
/** The spender: the same Instance key, because the authoriser and the spender are one Instance. */
|
|
129
|
+
readonly sub: InstanceKeyId;
|
|
130
|
+
/** Exactly `'percayso-cloud'`, and checked, not merely present. */
|
|
131
|
+
readonly aud: PercaysoCloudAudience;
|
|
132
|
+
/** The most the Instance may spend on Percayso Cloud services in one period, in whole cents. */
|
|
133
|
+
readonly cap_cents: Cents;
|
|
134
|
+
/** The period rule the cap is per. Opaque; the canon sets its value. */
|
|
135
|
+
readonly period: SettlementPeriodRule;
|
|
136
|
+
/** Issued-at, in **seconds** since the Unix epoch. */
|
|
137
|
+
readonly iat: number;
|
|
138
|
+
/**
|
|
139
|
+
* Expiry, in **seconds** since the Unix epoch. The owner's choice, bounded by a
|
|
140
|
+
* canon figure. An authorisation outlives many periods.
|
|
141
|
+
*/
|
|
142
|
+
readonly exp: number;
|
|
143
|
+
/** The authorisation's own id, unique, which every consumption row later cites. */
|
|
144
|
+
readonly jti: string;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* The Instance presenting its owner's standing authorisation, under the owner's
|
|
148
|
+
* assertion (`present-standing-authorisation`).
|
|
149
|
+
*/
|
|
150
|
+
export interface StandingAuthorisationRequest {
|
|
151
|
+
/** The compact {@link StandingAuthorisationClaims}, exactly as the Instance key signed it. */
|
|
152
|
+
readonly standingAuthorisation: string;
|
|
153
|
+
/**
|
|
154
|
+
* The Instance key's public half, as the JSON text of a public JSON Web Key. Its
|
|
155
|
+
* RFC 7638 thumbprint must be the authorisation's `kid`, so the key that verifies
|
|
156
|
+
* the authorisation is the key it names, and no other.
|
|
157
|
+
*/
|
|
158
|
+
readonly instanceKey: string;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Cayso's act: the acknowledgement that it holds a standing authorisation for this
|
|
162
|
+
* Instance key, signed by a Cayso issuer key in CAY-0072's format (CMTY-0018 §1).
|
|
163
|
+
* The Cloud verifies it against the one Cayso issuer in its registry and meters
|
|
164
|
+
* against it. It carries no wallet, no account, no Citizen and no Instance ID.
|
|
165
|
+
*
|
|
166
|
+
* It expires at the end of the period after the one it was issued in, so a
|
|
167
|
+
* revocation reaches the Cloud within one period without the Cloud asking Cayso
|
|
168
|
+
* anything on the request path.
|
|
169
|
+
*/
|
|
170
|
+
export interface AuthorisationAcknowledgementClaims {
|
|
171
|
+
/** The Cayso issuer that signed it. */
|
|
172
|
+
readonly iss: string;
|
|
173
|
+
/** Exactly `'percayso-cloud'`. */
|
|
174
|
+
readonly aud: PercaysoCloudAudience;
|
|
175
|
+
/** The acknowledged authorisation's `jti`. */
|
|
176
|
+
readonly authorisation: string;
|
|
177
|
+
/**
|
|
178
|
+
* The Instance key the authorisation was signed with, which the Cloud verifies
|
|
179
|
+
* every request from this Instance against. Not the header's `kid`, which names
|
|
180
|
+
* Cayso's signing key.
|
|
181
|
+
*/
|
|
182
|
+
readonly instance_kid: InstanceKeyId;
|
|
183
|
+
/** The cap, as the authorisation stated it, in whole cents. */
|
|
184
|
+
readonly cap_cents: Cents;
|
|
185
|
+
/** The period rule, as the authorisation stated it. */
|
|
186
|
+
readonly period: SettlementPeriodRule;
|
|
187
|
+
/** Issued-at, in **seconds** since the Unix epoch. */
|
|
188
|
+
readonly iat: number;
|
|
189
|
+
/** Expiry, in **seconds** since the Unix epoch. */
|
|
190
|
+
readonly exp: number;
|
|
191
|
+
}
|
|
192
|
+
/** Cayso holds the authorisation, and here is its acknowledgement for the Cloud. */
|
|
193
|
+
export interface StandingAuthorisationAcknowledged {
|
|
194
|
+
readonly outcome: 'acknowledged';
|
|
195
|
+
/** The compact {@link AuthorisationAcknowledgementClaims}, signed by Cayso. Carried, never edited. */
|
|
196
|
+
readonly acknowledgement: string;
|
|
197
|
+
}
|
|
198
|
+
/** The authorisation was refused, with one member of the closed union. Nothing was bound. */
|
|
199
|
+
export interface StandingAuthorisationRefused {
|
|
200
|
+
readonly outcome: 'refused';
|
|
201
|
+
readonly error: StandingAuthorisationRefusal;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The ONE declared answer to `present-standing-authorisation`, discriminated by
|
|
205
|
+
* `outcome`. A consumer switches on `outcome` and never sniffs which fields are
|
|
206
|
+
* present.
|
|
207
|
+
*/
|
|
208
|
+
export type StandingAuthorisationResponse = StandingAuthorisationAcknowledged | StandingAuthorisationRefused;
|
|
209
|
+
/**
|
|
210
|
+
* Why a standing authorisation was refused. Closed: a consumer renders a member by
|
|
211
|
+
* its name and never pattern-matches on prose, and a new reason is a new member
|
|
212
|
+
* and a contract version. Every member means the same thing: nothing was bound and
|
|
213
|
+
* no acknowledgement was signed.
|
|
214
|
+
*/
|
|
215
|
+
export type StandingAuthorisationRefusal =
|
|
216
|
+
/**
|
|
217
|
+
* The verification method is outside the money-grade assurance profile
|
|
218
|
+
* (`ASSURANCE_POLICY['present-standing-authorisation']`). `dev-bypass` is never
|
|
219
|
+
* inside it.
|
|
220
|
+
*/
|
|
221
|
+
'assurance_not_money_grade'
|
|
222
|
+
/** No wallet is bound to the verified holder now, so there is no wallet to spend from. */
|
|
223
|
+
| 'wallet_has_no_live_binding'
|
|
224
|
+
/**
|
|
225
|
+
* Not a compact assertion in CAY-0072's format, or its claims are not exactly the
|
|
226
|
+
* closed set of {@link StandingAuthorisationClaims}.
|
|
227
|
+
*/
|
|
228
|
+
| 'authorisation_malformed'
|
|
229
|
+
/** The Instance key presented is not a public JSON Web Key Cayso can verify with. */
|
|
230
|
+
| 'instance_key_malformed'
|
|
231
|
+
/** The presented key's thumbprint is not the authorisation's `kid`. */
|
|
232
|
+
| 'instance_key_not_the_kid'
|
|
233
|
+
/** The signature does not verify over the bytes presented. */
|
|
234
|
+
| 'authorisation_signature_invalid'
|
|
235
|
+
/** `iss` or `sub` is not the key that signed it: the authoriser and the spender are one Instance key. */
|
|
236
|
+
| 'authorisation_not_signed_by_its_spender'
|
|
237
|
+
/** `aud` is not `'percayso-cloud'`. */
|
|
238
|
+
| 'authorisation_audience_wrong'
|
|
239
|
+
/** `exp` is at or before now. */
|
|
240
|
+
| 'authorisation_expired'
|
|
241
|
+
/** `iat` is further ahead of now than the clock-skew tolerance. */
|
|
242
|
+
| 'authorisation_issued_in_the_future'
|
|
243
|
+
/** `exp` is further ahead than the canon's longest authorisation allows. */
|
|
244
|
+
| 'authorisation_outlives_its_ceiling'
|
|
245
|
+
/** `period` names no period rule Cayso publishes. */
|
|
246
|
+
| 'settlement_period_rule_not_recognised'
|
|
247
|
+
/**
|
|
248
|
+
* The `jti` was already presented with different claims. Two authorisations cannot
|
|
249
|
+
* share the id every consumption row cites, so neither is answered.
|
|
250
|
+
*/
|
|
251
|
+
| 'authorisation_jti_reused_for_a_different_authorisation'
|
|
252
|
+
/** The owner revoked this authorisation. It is never acknowledged again. */
|
|
253
|
+
| 'authorisation_revoked'
|
|
254
|
+
/** The cap is more than this holder may delegate. */
|
|
255
|
+
| 'cap_not_delegable'
|
|
256
|
+
/** The Instance key is already bound to a different wallet, and a key spends from one. */
|
|
257
|
+
| 'instance_key_bound_to_another_wallet';
|
|
258
|
+
/** The kind of contribution a row measures: the three of the Community map's #3. Closed. */
|
|
259
|
+
export type ContributionType = 'storage' | 'compute' | 'full-node';
|
|
260
|
+
/**
|
|
261
|
+
* The period a settlement assertion settles: its id, made by the period rule, and
|
|
262
|
+
* the UTC instants that bound it, in **seconds** since the Unix epoch. Block height
|
|
263
|
+
* replaces the instants as the ordering clock once there is a chain (CAY-0006).
|
|
264
|
+
*/
|
|
265
|
+
export interface SettlementPeriod {
|
|
266
|
+
readonly id: SettlementPeriodId;
|
|
267
|
+
readonly starts_at: number;
|
|
268
|
+
readonly ends_at: number;
|
|
269
|
+
}
|
|
270
|
+
/** Why a contribution row is withheld rather than paid. Earnings withheld are not lost. */
|
|
271
|
+
export type ContributionWithheldReason =
|
|
272
|
+
/** The Node is bound to no wallet yet (CMTY-0018 §4). */
|
|
273
|
+
'node_not_bound'
|
|
274
|
+
/** The Node did not pass its ladder gate this period. */
|
|
275
|
+
| 'ladder_gate_not_passed';
|
|
276
|
+
/** The row passed its ladder gate, and its amount is payable. */
|
|
277
|
+
export interface ContributionQualified {
|
|
278
|
+
readonly gate: 'passed';
|
|
279
|
+
/** The Node's ladder position, as the Cloud names it. Opaque here. */
|
|
280
|
+
readonly position: string;
|
|
281
|
+
}
|
|
282
|
+
/** The row is carried and its amount withheld, with the reason. */
|
|
283
|
+
export interface ContributionWithheld {
|
|
284
|
+
readonly gate: 'withheld';
|
|
285
|
+
/** The Node's ladder position, as the Cloud names it. Opaque here. */
|
|
286
|
+
readonly position: string;
|
|
287
|
+
readonly reason: ContributionWithheldReason;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Whether a row qualified. A union rather than a flag and an optional reason, so a
|
|
291
|
+
* withheld row without a reason, or a qualified row with one, is not expressible.
|
|
292
|
+
*/
|
|
293
|
+
export type ContributionQualification = ContributionQualified | ContributionWithheld;
|
|
294
|
+
/**
|
|
295
|
+
* One contribution row: one Node and one contribution type, measured on the Core
|
|
296
|
+
* side by the challenger and the gateway, never as the Node reported it.
|
|
297
|
+
*/
|
|
298
|
+
export interface ContributionRow {
|
|
299
|
+
readonly node_id: NodeId;
|
|
300
|
+
readonly type: ContributionType;
|
|
301
|
+
/** How much was contributed, in `unit`s. */
|
|
302
|
+
readonly quantity: number;
|
|
303
|
+
/** What `quantity` counts, for example GB-hours held and proved. Open. */
|
|
304
|
+
readonly unit: string;
|
|
305
|
+
/** The fraction of the availability contract delivered, from nought to one. */
|
|
306
|
+
readonly fulfilment: number;
|
|
307
|
+
readonly qualified: ContributionQualification;
|
|
308
|
+
/** What the Store calculated under the rate of the Node's contract, in whole cents. */
|
|
309
|
+
readonly amount_cents: Cents;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* One consumption row: one authorisation and one service, metered by the gateway
|
|
313
|
+
* and the storage rendezvous. Keyed by the authorisation's `jti` alone, never by an
|
|
314
|
+
* Instance ID (CAY-0059 §6).
|
|
315
|
+
*/
|
|
316
|
+
export interface ConsumptionRow {
|
|
317
|
+
/** The `jti` of the standing authorisation this consumption was metered against. */
|
|
318
|
+
readonly authorisation: string;
|
|
319
|
+
/** The service consumed, for example inference or storage. Open. */
|
|
320
|
+
readonly service: string;
|
|
321
|
+
/** How much was consumed, in `unit`s. */
|
|
322
|
+
readonly quantity: number;
|
|
323
|
+
/** What `quantity` counts. Open. */
|
|
324
|
+
readonly unit: string;
|
|
325
|
+
readonly amount_cents: Cents;
|
|
326
|
+
/** The cap as the acknowledgement stated it, so Cayso can see the Cloud stayed inside it. */
|
|
327
|
+
readonly cap_cents: Cents;
|
|
328
|
+
}
|
|
329
|
+
/** The sums of both legs, so a verifier refuses a row set that does not add before reading it. */
|
|
330
|
+
export interface SettlementTotals {
|
|
331
|
+
readonly contribution_cents: Cents;
|
|
332
|
+
readonly consumption_cents: Cents;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* One period's settlement, signed by the Contribution Store with a key whose public
|
|
336
|
+
* half is a registered Cayso issuer under its own `kid` (CAY-0030), in CAY-0072's
|
|
337
|
+
* format (CMTY-0018 §2). One per period per environment.
|
|
338
|
+
*/
|
|
339
|
+
export interface SettlementAssertionClaims {
|
|
340
|
+
readonly iss: ContributionStoreIssuer;
|
|
341
|
+
/** Exactly `'cayso'`. */
|
|
342
|
+
readonly aud: 'cayso';
|
|
343
|
+
readonly period: SettlementPeriod;
|
|
344
|
+
/**
|
|
345
|
+
* The hash over the period's rows in the Store. Opaque here: how it is made, and
|
|
346
|
+
* who writes it to the chain, are community.documentation#24's.
|
|
347
|
+
*/
|
|
348
|
+
readonly commitment: string;
|
|
349
|
+
readonly contribution: readonly ContributionRow[];
|
|
350
|
+
readonly consumption: readonly ConsumptionRow[];
|
|
351
|
+
readonly totals: SettlementTotals;
|
|
352
|
+
/** The period's id, and the idempotency key: the same assertion presented twice is a no-op. */
|
|
353
|
+
readonly jti: string;
|
|
354
|
+
/** Issued-at, in **seconds** since the Unix epoch. */
|
|
355
|
+
readonly iat: number;
|
|
356
|
+
/** Expiry, in **seconds** since the Unix epoch. */
|
|
357
|
+
readonly exp: number;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* The Contribution Store presenting one period's settlement assertion, under its
|
|
361
|
+
* own registered issuer and no person's assertion.
|
|
362
|
+
*/
|
|
363
|
+
export interface SettlementAssertionRequest {
|
|
364
|
+
/** The compact {@link SettlementAssertionClaims}, exactly as the Store signed it. */
|
|
365
|
+
readonly settlementAssertion: string;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* The period was settled whole. Answered for the presentation that settled it and
|
|
369
|
+
* for every replay of the same assertion, in the same shape.
|
|
370
|
+
*/
|
|
371
|
+
export interface SettlementAssertionSettled {
|
|
372
|
+
readonly outcome: 'settled';
|
|
373
|
+
/** The settled assertion's `jti`: the period's id. */
|
|
374
|
+
readonly jti: string;
|
|
375
|
+
}
|
|
376
|
+
/** The assertion as a whole was refused. No row is named, because none was read as a fact. */
|
|
377
|
+
export interface SettlementAssertionRefused {
|
|
378
|
+
readonly outcome: 'refused';
|
|
379
|
+
readonly error: SettlementAssertionLevelRefusal;
|
|
380
|
+
readonly leg: null;
|
|
381
|
+
readonly row: null;
|
|
382
|
+
}
|
|
383
|
+
/** The first failing row is on the contribution leg. Nothing was settled. */
|
|
384
|
+
export interface ContributionRowRefused {
|
|
385
|
+
readonly outcome: 'refused';
|
|
386
|
+
readonly error: ContributionRowRefusal;
|
|
387
|
+
readonly leg: 'contribution';
|
|
388
|
+
/** The row's zero-based position in the contribution leg as signed. */
|
|
389
|
+
readonly row: number;
|
|
390
|
+
}
|
|
391
|
+
/** The first failing row is on the consumption leg. Nothing was settled. */
|
|
392
|
+
export interface ConsumptionRowRefused {
|
|
393
|
+
readonly outcome: 'refused';
|
|
394
|
+
readonly error: ConsumptionRowRefusal;
|
|
395
|
+
readonly leg: 'consumption';
|
|
396
|
+
/** The row's zero-based position in the consumption leg as signed. */
|
|
397
|
+
readonly row: number;
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* The ONE declared answer to a settlement assertion, discriminated by `outcome`,
|
|
401
|
+
* and a refusal by `leg`. A row reason always names its row and an assertion
|
|
402
|
+
* reason never does: the pairing is in the types, not in care.
|
|
403
|
+
*/
|
|
404
|
+
export type SettlementAssertionResponse = SettlementAssertionSettled | SettlementAssertionRefused | ContributionRowRefused | ConsumptionRowRefused;
|
|
405
|
+
/**
|
|
406
|
+
* Why a settlement assertion was refused as a whole, before any row was read as a
|
|
407
|
+
* fact.
|
|
408
|
+
*/
|
|
409
|
+
export type SettlementAssertionLevelRefusal =
|
|
410
|
+
/**
|
|
411
|
+
* Not a compact assertion in CAY-0072's format, or its claims are not exactly the
|
|
412
|
+
* closed set of {@link SettlementAssertionClaims}.
|
|
413
|
+
*/
|
|
414
|
+
'settlement_malformed'
|
|
415
|
+
/** `iss` is not a Store issuer this deployment's registry holds, or the `kid` is not one of its keys. */
|
|
416
|
+
| 'settlement_issuer_not_recognised'
|
|
417
|
+
/**
|
|
418
|
+
* `iss` names a Store issuer of another environment. A DEV assertion never
|
|
419
|
+
* settles on a MAIN ledger, and neither does any other pairing.
|
|
420
|
+
*/
|
|
421
|
+
| 'settlement_issuer_for_another_environment'
|
|
422
|
+
/** The signature does not verify over the bytes presented. */
|
|
423
|
+
| 'settlement_signature_invalid'
|
|
424
|
+
/** `aud` is not `'cayso'`. */
|
|
425
|
+
| 'settlement_audience_wrong'
|
|
426
|
+
/** `exp` is at or before now. */
|
|
427
|
+
| 'settlement_expired'
|
|
428
|
+
/** `iat` is further ahead of now than the clock-skew tolerance. */
|
|
429
|
+
| 'settlement_issued_in_the_future'
|
|
430
|
+
/** `jti` is not the period's id. */
|
|
431
|
+
| 'settlement_jti_not_the_period'
|
|
432
|
+
/**
|
|
433
|
+
* A different assertion already settled this period. The two cannot both be the
|
|
434
|
+
* period, so the second is refused, and the first stands.
|
|
435
|
+
*/
|
|
436
|
+
| 'settlement_period_already_settled_differently'
|
|
437
|
+
/** A leg's rows do not add to its total. Refused before any row is read. */
|
|
438
|
+
| 'settlement_totals_do_not_add';
|
|
439
|
+
/** Why the first failing contribution row failed. */
|
|
440
|
+
export type ContributionRowRefusal =
|
|
441
|
+
/**
|
|
442
|
+
* A qualified row names a Node bound to no wallet. An unbound Node's row is
|
|
443
|
+
* carried withheld (`node_not_bound`) and never settled to anybody.
|
|
444
|
+
*/
|
|
445
|
+
'contribution_node_not_bound';
|
|
446
|
+
/** Why the first failing consumption row failed. */
|
|
447
|
+
export type ConsumptionRowRefusal =
|
|
448
|
+
/** The row cites an authorisation Cayso never acknowledged. */
|
|
449
|
+
'consumption_authorisation_unknown'
|
|
450
|
+
/** The row cites an authorisation its owner revoked before the period. */
|
|
451
|
+
| 'consumption_authorisation_revoked'
|
|
452
|
+
/** The row's cap is not the cap the acknowledgement stated. */
|
|
453
|
+
| 'consumption_cap_not_the_acknowledged_cap'
|
|
454
|
+
/** The authorisation's running total in this period passes its cap at this row. */
|
|
455
|
+
| 'consumption_over_cap';
|
|
456
|
+
/**
|
|
457
|
+
* Every reason a settlement assertion can be refused: the assertion's own, and each
|
|
458
|
+
* leg's. Closed, so a consumer's map over it is total.
|
|
459
|
+
*/
|
|
460
|
+
export type SettlementAssertionRefusal = SettlementAssertionLevelRefusal | ContributionRowRefusal | ConsumptionRowRefusal;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 Percayso Community
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* GENERATED FILE — do not edit by hand.
|
|
3
3
|
*
|
|
4
4
|
* Produced by `scripts/generate-contract-schema.ts` from the published types
|
|
5
|
-
* (`wallet.ts`, `purchase.ts`, `assertion.ts`, `citizenship.ts`, `errors.ts`
|
|
5
|
+
* (`wallet.ts`, `purchase.ts`, `assertion.ts`, `citizenship.ts`, `errors.ts`
|
|
6
|
+
* and the rest of the barrel's surface, with `operator.ts` under its own key)
|
|
6
7
|
* and the
|
|
7
8
|
* package's own value exports. Regenerate with `pnpm --filter @percayso-community/cayso-contracts generate-schema`.
|
|
8
9
|
*
|