@percayso-community/cayso-contracts 0.26.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.
@@ -319,6 +319,13 @@
319
319
  * was served, as `'provision-citizenship'` was, and it is served at
320
320
  * `ROUTES.commercialPayment`.
321
321
  *
322
+ * `'make-citizen-transfer'` is a Citizen transferring Cayso from their own Citizen
323
+ * Wallet to another Citizen's (CAY-0088). It is not a second use of
324
+ * `'make-commercial-payment'`, which always has an organisation on one side, nor of
325
+ * `'place-quote'`, which prices cents against sterling: a transfer quotes nothing. A
326
+ * credential minted to place a quote must not thereby move cents to somebody without
327
+ * a match, nor the reverse. It is served at `ROUTES.citizenTransfer`.
328
+ *
322
329
  * `'place-quote'`, `'withdraw-quote'` and `'request-buy-back'` are the citizen
323
330
  * market's three acts (CAY-0080, Open decision Q). They are three operations
324
331
  * because they are three acts: a credential minted to withdraw a quote must not
@@ -363,7 +370,7 @@
363
370
  * Contribution Store's assertion, which no person presents and which therefore has
364
371
  * no operation here. It is classified before it is served.
365
372
  */
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';
373
+ 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' | 'make-citizen-transfer' | 'place-quote' | 'withdraw-quote' | 'request-buy-back' | 'read-citizen-market' | 'read-marketplace-receipt' | 'settle-marketplace-order' | 'settle-marketplace-refund' | 'present-standing-authorisation';
367
374
  /**
368
375
  * An operation key belonging to a deployment's OWN surfaces rather than to this
369
376
  * contract — operator work, above all. Deliberately not enumerated: this package
package/dist/assurance.js CHANGED
@@ -325,6 +325,24 @@ export const ASSURANCE_POLICY = {
325
325
  'money-grade: anything but the development bypass. The bar applies on both routes, and to ' +
326
326
  'an Authorised User it applies again at every payment, not only when the allowance was granted.',
327
327
  },
328
+ // A Citizen transferring to another Citizen (CAY-0088 §2). Money-grade, at the
329
+ // purchase path's bar, for the commercial payment's reason: value leaves a holder
330
+ // for somebody else, and a bar no issuer can clear would close the transfer on
331
+ // every deployment. An allowlist, so a future method is admissible only when
332
+ // somebody decides it here.
333
+ 'make-citizen-transfer': {
334
+ operation: 'make-citizen-transfer',
335
+ assurance: 'required',
336
+ decisions: {
337
+ // Asserts nothing; permanently refused wherever "identity-verified" is meant.
338
+ 'dev-bypass': 'refused',
339
+ document: 'accepted',
340
+ 'document-and-biometric': 'accepted',
341
+ },
342
+ rationale: 'A Citizen transfer moves value out of one holder to another, so it is money-grade: ' +
343
+ 'anything but the development bypass. An unverified holder must never be able to send, ' +
344
+ 'because sending is how value reaches somebody else.',
345
+ },
328
346
  // The citizen market's three acts (CAY-0080 §7, Open decision Q). All three are
329
347
  // money-grade and all three are allowlists, at the purchase path's bar: the acting
330
348
  // party is a Citizen, and a bar no issuer can yet clear would shut the market on
@@ -505,6 +523,7 @@ export const OPERATION_FOR_ROUTE = {
505
523
  purchaseResult: 'read-purchase-result',
506
524
  purchaseCancel: 'cancel-purchase',
507
525
  commercialPayment: 'make-commercial-payment',
526
+ citizenTransfer: 'make-citizen-transfer',
508
527
  citizenMarket: 'read-citizen-market',
509
528
  placeQuote: 'place-quote',
510
529
  withdrawQuote: 'withdraw-quote',
@@ -0,0 +1,110 @@
1
+ /**
2
+ * `citizen-transfer` — the request, the answer and the closed refusal union for a
3
+ * Citizen transferring Cayso to another Citizen (CAY-0088).
4
+ *
5
+ * A Citizen transfer is unrestricted cents moving directly from the caller's own
6
+ * Citizen Wallet to another Citizen Wallet, as one `transfer` movement. It is not a
7
+ * quoted sale and it is not the citizen market: no price is quoted, no sterling moves,
8
+ * and the Treasury takes no part. A transfer between a pair that mirrors market fills
9
+ * is watched for by the transfer-pattern alarm (CAY-0080 §5.8) and is reported, never
10
+ * reversed. Served at `ROUTES.citizenTransfer`.
11
+ *
12
+ * ## One movement or nothing, so there is no status
13
+ *
14
+ * As with the commercial payment (CAY-0079 §5) there is no sterling leg and no
15
+ * provider, so there is nothing to authorise first and capture later. The answer is a
16
+ * {@link CitizenTransferMade}, carrying the one movement that was written, or a
17
+ * {@link CitizenTransferRefused}, carrying one reason and meaning nothing was written.
18
+ *
19
+ * ## Replay under one key
20
+ *
21
+ * The key is unique together with the sending wallet. A repeat with the same key, the
22
+ * same payee and the same cents answers the movement already written, in the same
23
+ * shape; a repeat with the same key and anything different is refused with
24
+ * `idempotency_key_reused_for_a_different_transfer`. A transfer is never reversed: a
25
+ * Citizen who wants cents back asks for a new transfer the other way, made by the
26
+ * other Citizen under their own key.
27
+ *
28
+ * ## The sender is never named in the request
29
+ *
30
+ * The sending wallet is the verified assertion's subject's own Citizen Wallet,
31
+ * resolved inside the service (CAY-0021). A request that named the sending wallet
32
+ * would be the caller's claim about whose cents these are. The payee is a wallet id,
33
+ * given by the payee as they would give an address, and never a Percayso identity.
34
+ *
35
+ * ## What this file must not decide
36
+ *
37
+ * - **No figures.** No ceiling, rate or threshold is restated here (CAY-0088 §4).
38
+ * - **One payee.** A split is not designed.
39
+ * - **Restricted cents never move.** A restricted lot is not transferable (CAY-0074),
40
+ * so a wallet short of unrestricted cents is short, whatever else it holds.
41
+ */
42
+ import type { Cents, Millis } from './wallet.js';
43
+ /** A Citizen transferring cents from their own Citizen Wallet to another, under one key. */
44
+ export interface CitizenTransferRequest {
45
+ /** The Citizen Wallet the cents arrive in. A wallet id, never a Percayso identity. */
46
+ readonly payeeWalletId: string;
47
+ /** Whole cents, above zero. Anything else is refused `amount_not_positive_whole_cents`. */
48
+ readonly cents: Cents;
49
+ /** Caller-generated, unique per sending wallet. The same key never moves cents twice; a repeat REPLAYS. */
50
+ readonly idempotencyKey: string;
51
+ }
52
+ /**
53
+ * The one movement a Citizen transfer wrote. Final and append-only. It names the
54
+ * sending wallet because the caller is owed the handle their own cents left from, and
55
+ * names no person.
56
+ */
57
+ export interface CitizenTransfer {
58
+ /** The movement that carried the cents. */
59
+ readonly movementId: string;
60
+ readonly fromWalletId: string;
61
+ readonly payeeWalletId: string;
62
+ readonly cents: Cents;
63
+ readonly transferredAt: Millis;
64
+ }
65
+ /** The transfer was made. Answered for the request that made it and for every replay of its key. */
66
+ export interface CitizenTransferMade {
67
+ readonly outcome: 'transferred';
68
+ readonly transfer: CitizenTransfer;
69
+ }
70
+ /** The transfer was refused, with one member of the closed union. Nothing was written. */
71
+ export interface CitizenTransferRefused {
72
+ readonly outcome: 'refused';
73
+ readonly error: CitizenTransferRefusal;
74
+ }
75
+ /** The ONE declared answer to a Citizen transfer, discriminated by `outcome`. */
76
+ export type CitizenTransferResponse = CitizenTransferMade | CitizenTransferRefused;
77
+ /**
78
+ * Why a Citizen transfer was refused: CAY-0088 §3's set, closed. A consumer renders a
79
+ * member by its name. Every member means the same thing about money: nothing moved.
80
+ */
81
+ export type CitizenTransferRefusal =
82
+ /**
83
+ * The verification method is outside the money-grade assurance profile
84
+ * (`ASSURANCE_POLICY['make-citizen-transfer']`). `dev-bypass` is never inside it.
85
+ */
86
+ 'assurance_not_money_grade'
87
+ /** The verified subject resolves to no Citizen Wallet. A transfer never provisions one. */
88
+ | 'sender_has_no_citizen_wallet'
89
+ /** No wallet has the payee's id. */
90
+ | 'payee_wallet_not_found'
91
+ /** The payee's wallet is an Organisation Wallet or the Treasury. Organisations are paid by commercial payment. */
92
+ | 'payee_wallet_not_a_citizens'
93
+ /** No citizen is bound to the payee's wallet now, for example because the binding was erased. */
94
+ | 'payee_wallet_has_no_live_binding'
95
+ /** The payee's wallet is the sender's own. */
96
+ | 'payee_is_the_sender'
97
+ /** The cents are zero, negative or not a whole number. */
98
+ | 'amount_not_positive_whole_cents'
99
+ /**
100
+ * The sender's unrestricted cents are short. Restricted cents are never counted and
101
+ * never drawn (CAY-0074), so a wallet holding enough only once restricted cents are
102
+ * included is still short.
103
+ */
104
+ | 'unrestricted_cents_insufficient'
105
+ /** A holding the transfer would draw is frozen. */
106
+ | 'cents_frozen'
107
+ /** The key was already used by this sending wallet for a different payee or a different number of cents. */
108
+ | 'idempotency_key_reused_for_a_different_transfer'
109
+ /** Too many concurrent draws on the sending wallet. Nothing moved; retry under the same key. */
110
+ | 'carve_contended';
@@ -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 {};
package/dist/client.d.ts CHANGED
@@ -70,6 +70,7 @@
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
72
  import type { StandingAuthorisationAcknowledged, StandingAuthorisationRequest } from './cloud-settlement.js';
73
+ import type { CitizenTransferMade, CitizenTransferRequest } from './citizen-transfer.js';
73
74
  import type { CommercialPaymentMade, CommercialPaymentRequest } from './commercial-payment.js';
74
75
  import type { MarketplaceOrderRequest, MarketplaceOrderSettled } from './marketplace-settlement.js';
75
76
  import type { OrganisationView } from './organisation.js';
@@ -213,6 +214,17 @@ export interface CaysoClient {
213
214
  * refusals do. A refusal means nothing moved.
214
215
  */
215
216
  makeCommercialPayment(req: CommercialPaymentRequest): Promise<CommercialPaymentMade>;
217
+ /**
218
+ * Transfer unrestricted cents from the caller's own Citizen Wallet to another
219
+ * Citizen Wallet — or REPLAY a transfer already made under the same key (CAY-0088).
220
+ *
221
+ * The sending wallet is never named: it is the verified holder's own. A replay with
222
+ * the same key, payee and cents answers the movement already written. A refusal
223
+ * arrives as a thrown {@link CaysoApiError} whose `code` is a
224
+ * `CitizenTransferRefusal` member, one of the gate's codes, or a seam code. A
225
+ * refusal means nothing moved.
226
+ */
227
+ makeCitizenTransfer(req: CitizenTransferRequest): Promise<CitizenTransferMade>;
216
228
  /**
217
229
  * Read the citizen market as the caller sees it (CAY-0080 §1.4): the published
218
230
  * value and its band, both bounds per quote unit, the best bid and the best ask with
package/dist/client.js CHANGED
@@ -221,6 +221,16 @@ function buildClient(options, internals) {
221
221
  idempotencyKey: req.idempotencyKey,
222
222
  });
223
223
  },
224
+ async makeCitizenTransfer(req) {
225
+ return requestJson({
226
+ method: ROUTES.citizenTransfer.method,
227
+ path: ROUTES.citizenTransfer.path,
228
+ // Safe to repeat only because of the key: a repeat replays the transfer.
229
+ idempotent: typeof req.idempotencyKey === 'string' && req.idempotencyKey.length > 0,
230
+ body: req,
231
+ idempotencyKey: req.idempotencyKey,
232
+ });
233
+ },
224
234
  async getCitizenMarket() {
225
235
  return requestJson({
226
236
  method: ROUTES.citizenMarket.method,
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  export const CONTRACT_SCHEMA = {
17
- "contractVersion": "0.26.0",
17
+ "contractVersion": "0.27.0",
18
18
  "packageName": "@percayso-community/cayso-contracts",
19
19
  "capabilities": {
20
20
  "wallet": "cayso.wallet",
@@ -57,6 +57,10 @@ export const CONTRACT_SCHEMA = {
57
57
  "method": "POST",
58
58
  "path": "/api/commercial-payments"
59
59
  },
60
+ "citizenTransfer": {
61
+ "method": "POST",
62
+ "path": "/api/citizen-transfers"
63
+ },
60
64
  "citizenMarket": {
61
65
  "method": "GET",
62
66
  "path": "/api/citizen-market"
@@ -654,6 +658,9 @@ export const CONTRACT_SCHEMA = {
654
658
  {
655
659
  "literal": "commercial_payment_store_not_configured"
656
660
  },
661
+ {
662
+ "literal": "citizen_transfer_store_not_configured"
663
+ },
657
664
  {
658
665
  "literal": "citizen_market_not_configured"
659
666
  },
@@ -696,6 +703,9 @@ export const CONTRACT_SCHEMA = {
696
703
  {
697
704
  "ref": "CommercialPaymentRefusal"
698
705
  },
706
+ {
707
+ "ref": "CitizenTransferRefusal"
708
+ },
699
709
  {
700
710
  "ref": "QuotePlacementRefusal"
701
711
  },
@@ -893,6 +903,163 @@ export const CONTRACT_SCHEMA = {
893
903
  }
894
904
  }
895
905
  },
906
+ "CitizenTransfer": {
907
+ "kind": "object",
908
+ "properties": {
909
+ "movementId": {
910
+ "type": {
911
+ "scalar": "string"
912
+ },
913
+ "readonly": true,
914
+ "optional": false
915
+ },
916
+ "fromWalletId": {
917
+ "type": {
918
+ "scalar": "string"
919
+ },
920
+ "readonly": true,
921
+ "optional": false
922
+ },
923
+ "payeeWalletId": {
924
+ "type": {
925
+ "scalar": "string"
926
+ },
927
+ "readonly": true,
928
+ "optional": false
929
+ },
930
+ "cents": {
931
+ "type": {
932
+ "ref": "Cents"
933
+ },
934
+ "readonly": true,
935
+ "optional": false
936
+ },
937
+ "transferredAt": {
938
+ "type": {
939
+ "ref": "Millis"
940
+ },
941
+ "readonly": true,
942
+ "optional": false
943
+ }
944
+ }
945
+ },
946
+ "CitizenTransferMade": {
947
+ "kind": "object",
948
+ "properties": {
949
+ "outcome": {
950
+ "type": {
951
+ "literal": "transferred"
952
+ },
953
+ "readonly": true,
954
+ "optional": false
955
+ },
956
+ "transfer": {
957
+ "type": {
958
+ "ref": "CitizenTransfer"
959
+ },
960
+ "readonly": true,
961
+ "optional": false
962
+ }
963
+ }
964
+ },
965
+ "CitizenTransferRefusal": {
966
+ "kind": "alias",
967
+ "of": {
968
+ "union": [
969
+ {
970
+ "literal": "assurance_not_money_grade"
971
+ },
972
+ {
973
+ "literal": "sender_has_no_citizen_wallet"
974
+ },
975
+ {
976
+ "literal": "payee_wallet_not_found"
977
+ },
978
+ {
979
+ "literal": "payee_wallet_not_a_citizens"
980
+ },
981
+ {
982
+ "literal": "payee_wallet_has_no_live_binding"
983
+ },
984
+ {
985
+ "literal": "payee_is_the_sender"
986
+ },
987
+ {
988
+ "literal": "amount_not_positive_whole_cents"
989
+ },
990
+ {
991
+ "literal": "unrestricted_cents_insufficient"
992
+ },
993
+ {
994
+ "literal": "cents_frozen"
995
+ },
996
+ {
997
+ "literal": "idempotency_key_reused_for_a_different_transfer"
998
+ },
999
+ {
1000
+ "literal": "carve_contended"
1001
+ }
1002
+ ]
1003
+ }
1004
+ },
1005
+ "CitizenTransferRefused": {
1006
+ "kind": "object",
1007
+ "properties": {
1008
+ "outcome": {
1009
+ "type": {
1010
+ "literal": "refused"
1011
+ },
1012
+ "readonly": true,
1013
+ "optional": false
1014
+ },
1015
+ "error": {
1016
+ "type": {
1017
+ "ref": "CitizenTransferRefusal"
1018
+ },
1019
+ "readonly": true,
1020
+ "optional": false
1021
+ }
1022
+ }
1023
+ },
1024
+ "CitizenTransferRequest": {
1025
+ "kind": "object",
1026
+ "properties": {
1027
+ "payeeWalletId": {
1028
+ "type": {
1029
+ "scalar": "string"
1030
+ },
1031
+ "readonly": true,
1032
+ "optional": false
1033
+ },
1034
+ "cents": {
1035
+ "type": {
1036
+ "ref": "Cents"
1037
+ },
1038
+ "readonly": true,
1039
+ "optional": false
1040
+ },
1041
+ "idempotencyKey": {
1042
+ "type": {
1043
+ "scalar": "string"
1044
+ },
1045
+ "readonly": true,
1046
+ "optional": false
1047
+ }
1048
+ }
1049
+ },
1050
+ "CitizenTransferResponse": {
1051
+ "kind": "alias",
1052
+ "of": {
1053
+ "union": [
1054
+ {
1055
+ "ref": "CitizenTransferMade"
1056
+ },
1057
+ {
1058
+ "ref": "CitizenTransferRefused"
1059
+ }
1060
+ ]
1061
+ }
1062
+ },
896
1063
  "Citizenship": {
897
1064
  "kind": "alias",
898
1065
  "of": {
@@ -1329,6 +1496,9 @@ export const CONTRACT_SCHEMA = {
1329
1496
  {
1330
1497
  "literal": "make-commercial-payment"
1331
1498
  },
1499
+ {
1500
+ "literal": "make-citizen-transfer"
1501
+ },
1332
1502
  {
1333
1503
  "literal": "place-quote"
1334
1504
  },
package/dist/errors.d.ts CHANGED
@@ -44,6 +44,7 @@
44
44
  import type { FounderClaimRefusal } from './citizenship.js';
45
45
  import type { BuyBackRefusal, QuotePlacementRefusal, QuoteWithdrawalRefusal } from './citizen-market.js';
46
46
  import type { SettlementAssertionRefusal, StandingAuthorisationRefusal } from './cloud-settlement.js';
47
+ import type { CitizenTransferRefusal } from './citizen-transfer.js';
47
48
  import type { CommercialPaymentRefusal } from './commercial-payment.js';
48
49
  import type { MarketplaceReceiptReadRefusal } from './marketplace-receipt.js';
49
50
  import type { MarketplaceOrderRefusal, MarketplaceRefundRefusal } from './marketplace-settlement.js';
@@ -119,6 +120,12 @@ export type CaysoApiErrorCode =
119
120
  * (CAY-0079 §3).
120
121
  */
121
122
  | 'commercial_payment_store_not_configured'
123
+ /**
124
+ * No Citizen transfer store is wired, so the route is closed (CAY-0088 §3). It
125
+ * describes the deployment and not the transfer, so it is not a member of the
126
+ * transfer's refusal union.
127
+ */
128
+ | 'citizen_transfer_store_not_configured'
122
129
  /**
123
130
  * The citizen market is shut on this deployment: no store is wired, or a figure
124
131
  * the book needs is not set in the canon and so not configured here (CAY-0080,
@@ -176,7 +183,7 @@ export type CaysoApiErrorCode =
176
183
  /** There is no such purchase under this caller's wallet. */
177
184
  | 'not_found'
178
185
  /** Something failed on the way and the refusal discloses nothing further. */
179
- | 'internal_error' | PurchaseFailureReason | PurchaseCancelRefusalReason | FounderClaimRefusal | CommercialPaymentRefusal | QuotePlacementRefusal | QuoteWithdrawalRefusal | BuyBackRefusal | MarketplaceReceiptReadRefusal | MarketplaceOrderRefusal | MarketplaceRefundRefusal | StandingAuthorisationRefusal | SettlementAssertionRefusal;
186
+ | 'internal_error' | PurchaseFailureReason | PurchaseCancelRefusalReason | FounderClaimRefusal | CommercialPaymentRefusal | CitizenTransferRefusal | QuotePlacementRefusal | QuoteWithdrawalRefusal | BuyBackRefusal | MarketplaceReceiptReadRefusal | MarketplaceOrderRefusal | MarketplaceRefundRefusal | StandingAuthorisationRefusal | SettlementAssertionRefusal;
180
187
  /**
181
188
  * The body of every refusal on this surface: one code, and nothing beside it.
182
189
  *
package/dist/index.d.ts CHANGED
@@ -76,6 +76,15 @@
76
76
  * this money surface gains that Piper's own contracts lack, since theirs share
77
77
  * one global version bumped across all twenty-two together (CAY-0026).
78
78
  *
79
+ * `0.26.0` → `0.27.0` publishes and SERVES the Citizen transfer (CAY-0088):
80
+ * `ROUTES.citizenTransfer`, `POST /api/citizen-transfers`, mapped to the new
81
+ * operation `'make-citizen-transfer'`, money-grade in `ASSURANCE_POLICY`; the client
82
+ * method `makeCitizenTransfer`; and `CaysoApiErrorCode` gains
83
+ * {@link CitizenTransferRefusal} by reference and the seam code
84
+ * `citizen_transfer_store_not_configured`. It is BREAKING in the package's sense
85
+ * because three closed tables grew. It is additive on the wire: no route a `0.26.0`
86
+ * consumer calls changed or answers anything new (CAY-0086).
87
+ *
79
88
  * `0.25.0` → `0.26.0` publishes the operator read surface on its own entry point,
80
89
  * `@percayso-community/cayso-contracts/operator` (CAY-0026 Amendment 4), and describes
81
90
  * it in the schema under `operator`: the movement list, the purchase list and the
@@ -513,7 +522,7 @@
513
522
  * have needed a breaking bump on their own. Under semver below `1.0.0` the minor
514
523
  * is where a breaking change goes, so the minor moves and the patch does not.
515
524
  */
516
- export declare const CONTRACT_VERSION: "0.26.0";
525
+ export declare const CONTRACT_VERSION: "0.27.0";
517
526
  /** The package's own name, so a consumer can name what it depends on. */
518
527
  export declare const packageName = "@percayso-community/cayso-contracts";
519
528
  /**
@@ -653,6 +662,7 @@ export type { HolderType, Millis, Cents, WalletRecord, Balance, Allowance, Walle
653
662
  export type { SignUpGrantTerms, SignUpGrant, CitizenshipNotProvisioned, CitizenshipProvisioned, CitizenshipFounderClaimed, Citizenship, CitizenshipView, FounderClaimRefusal, } from './citizenship.js';
654
663
  export type { OrganisationView } from './organisation.js';
655
664
  export type { CommercialPaymentAuthority, CommercialPaymentRequest, CommercialPayment, CommercialPaymentMade, CommercialPaymentRefused, CommercialPaymentResponse, CommercialPaymentRefusal, } from './commercial-payment.js';
665
+ export type { CitizenTransferRequest, CitizenTransfer, CitizenTransferMade, CitizenTransferRefused, CitizenTransferResponse, CitizenTransferRefusal, } from './citizen-transfer.js';
656
666
  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';
657
667
  export type { MarketplaceReceiptSignatureAlgorithm, MarketplaceReceiptKeyId, MarketplaceSaleKind, MarketplaceReceiptLeg, MarketplaceSettlementReceiptStatement, HousePublisherChargeReceiptStatement, ThirdPartyRefundReceiptStatement, HousePublisherRefundReceiptStatement, MarketplaceReceiptStatement, MarketplaceReceipt, MarketplaceReceiptReadRequest, MarketplaceReceiptFound, MarketplaceNoMovement, MarketplaceReceiptReadRefusal, MarketplaceReceiptReadRefused, MarketplaceReceiptReadResponse, } from './marketplace-receipt.js';
658
668
  export type { StoreSignedStatement, MarketplaceOrderRequest, MarketplaceRefundRequest, MarketplaceOrderReceipt, MarketplaceRefundReceipt, MarketplaceOrderSettled, MarketplaceOrderRefused, MarketplaceOrderResponse, MarketplaceOrderRefusal, MarketplaceRefundSettled, MarketplaceRefundRefused, MarketplaceRefundResponse, MarketplaceRefundRefusal, } from './marketplace-settlement.js';
package/dist/index.js CHANGED
@@ -92,6 +92,15 @@
92
92
  * this money surface gains that Piper's own contracts lack, since theirs share
93
93
  * one global version bumped across all twenty-two together (CAY-0026).
94
94
  *
95
+ * `0.26.0` → `0.27.0` publishes and SERVES the Citizen transfer (CAY-0088):
96
+ * `ROUTES.citizenTransfer`, `POST /api/citizen-transfers`, mapped to the new
97
+ * operation `'make-citizen-transfer'`, money-grade in `ASSURANCE_POLICY`; the client
98
+ * method `makeCitizenTransfer`; and `CaysoApiErrorCode` gains
99
+ * {@link CitizenTransferRefusal} by reference and the seam code
100
+ * `citizen_transfer_store_not_configured`. It is BREAKING in the package's sense
101
+ * because three closed tables grew. It is additive on the wire: no route a `0.26.0`
102
+ * consumer calls changed or answers anything new (CAY-0086).
103
+ *
95
104
  * `0.25.0` → `0.26.0` publishes the operator read surface on its own entry point,
96
105
  * `@percayso-community/cayso-contracts/operator` (CAY-0026 Amendment 4), and describes
97
106
  * it in the schema under `operator`: the movement list, the purchase list and the
@@ -529,7 +538,7 @@
529
538
  * have needed a breaking bump on their own. Under semver below `1.0.0` the minor
530
539
  * is where a breaking change goes, so the minor moves and the patch does not.
531
540
  */
532
- export const CONTRACT_VERSION = '0.26.0';
541
+ export const CONTRACT_VERSION = '0.27.0';
533
542
  /** The package's own name, so a consumer can name what it depends on. */
534
543
  export const packageName = '@percayso-community/cayso-contracts';
535
544
  /**
package/dist/routes.d.ts CHANGED
@@ -76,6 +76,14 @@
76
76
  * (CAY-0079 §2). A path that took a payee's identity would make this route a
77
77
  * directory of identities for anyone holding a mandate.
78
78
  *
79
+ * ## Why `citizenTransfer` names only the payee, and never the sender
80
+ *
81
+ * `POST /api/citizen-transfers` is a Citizen transferring Cayso to another Citizen
82
+ * (CAY-0088). The body carries the payee's wallet id, the cents and the key. The
83
+ * sending wallet is NOT in the request: it is the verified subject's own Citizen
84
+ * Wallet, resolved inside `apps/api`, because a sending wallet the caller named would
85
+ * be the caller's claim about whose cents these are (CAY-0021).
86
+ *
79
87
  * ## Why the citizen market is FOUR PATHS, and none of them names a wallet
80
88
  *
81
89
  * `citizenMarket` reads the book, `placeQuote` places a quote, and `withdrawQuote`
@@ -146,6 +154,10 @@ export declare const ROUTES: {
146
154
  readonly method: "POST";
147
155
  readonly path: "/api/commercial-payments";
148
156
  };
157
+ readonly citizenTransfer: {
158
+ readonly method: "POST";
159
+ readonly path: "/api/citizen-transfers";
160
+ };
149
161
  readonly citizenMarket: {
150
162
  readonly method: "GET";
151
163
  readonly path: "/api/citizen-market";
package/dist/routes.js CHANGED
@@ -91,6 +91,14 @@
91
91
  * (CAY-0079 §2). A path that took a payee's identity would make this route a
92
92
  * directory of identities for anyone holding a mandate.
93
93
  *
94
+ * ## Why `citizenTransfer` names only the payee, and never the sender
95
+ *
96
+ * `POST /api/citizen-transfers` is a Citizen transferring Cayso to another Citizen
97
+ * (CAY-0088). The body carries the payee's wallet id, the cents and the key. The
98
+ * sending wallet is NOT in the request: it is the verified subject's own Citizen
99
+ * Wallet, resolved inside `apps/api`, because a sending wallet the caller named would
100
+ * be the caller's claim about whose cents these are (CAY-0021).
101
+ *
94
102
  * ## Why the citizen market is FOUR PATHS, and none of them names a wallet
95
103
  *
96
104
  * `citizenMarket` reads the book, `placeQuote` places a quote, and `withdrawQuote`
@@ -134,6 +142,7 @@ export const ROUTES = {
134
142
  purchaseResult: { method: 'GET', path: '/api/purchases/:purchaseId' },
135
143
  purchaseCancel: { method: 'POST', path: '/api/purchases/:purchaseId/cancel' },
136
144
  commercialPayment: { method: 'POST', path: '/api/commercial-payments' },
145
+ citizenTransfer: { method: 'POST', path: '/api/citizen-transfers' },
137
146
  citizenMarket: { method: 'GET', path: '/api/citizen-market' },
138
147
  placeQuote: { method: 'POST', path: '/api/quotes' },
139
148
  withdrawQuote: { method: 'POST', path: '/api/quote-withdrawals' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percayso-community/cayso-contracts",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "The versioned capability contract surface through which anything outside this repository reads a wallet. Published; keep it the surface of every consumer outside this tree, Piper and the Percayso Cloud, and nothing internal.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {