@peable.to/contracts 5.5.0 → 6.0.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/dist/cjs/resources/payments/social.js +72 -6
- package/dist/cjs/vocabulary/errors.js +1 -1
- package/dist/cjs/vocabulary/payments.js +16 -6
- package/dist/esm/resources/payments/social.js +72 -6
- package/dist/esm/vocabulary/errors.js +1 -1
- package/dist/esm/vocabulary/payments.js +15 -5
- package/dist/types/resources/payments/index.d.ts +41 -1
- package/dist/types/resources/payments/paymentIntents.d.ts +10 -0
- package/dist/types/resources/payments/social.d.ts +82 -5
- package/dist/types/resources/payments/testHelpers.d.ts +1 -0
- package/dist/types/vocabulary/errors.d.ts +1 -1
- package/dist/types/vocabulary/payments.d.ts +15 -6
- package/package.json +1 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.socialRoutes = exports.enrichSchema = exports.enrichParams = exports.socialPaymentsSchema = exports.socialPaymentSchema = exports.socialPaymentsQuery = exports.socialReceiveCursorSchema = exports.socialReceiveCursorQuery = exports.socialNextAddressSchema = exports.socialNextAddressParams = exports.socialPaymentSourceParams = exports.enrichmentResultSchema = exports.socialPaymentSourceSchema = void 0;
|
|
3
|
+
exports.socialRoutes = exports.enrichSchema = exports.enrichParams = exports.socialPaymentsSchema = exports.socialPaymentSchema = exports.socialPaymentsQuery = exports.socialReceiveAddressesSchema = exports.socialReceiveAddressSchema = exports.socialReceiveAddressesQuery = exports.socialReceiveCursorSchema = exports.socialReceiveCursorQuery = exports.socialNextAddressSchema = exports.socialNextAddressParams = exports.socialPaymentSourceParams = exports.enrichmentResultSchema = exports.socialPaymentSourceSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const objects_1 = require("../../common/objects");
|
|
6
|
+
const params_1 = require("../../common/params");
|
|
7
|
+
/** The highest BIP32 non-hardened child index, `int4`'s ceiling (`schema/valueSets.ts`). */
|
|
8
|
+
const MAX_DERIVATION_INDEX = 2147483647;
|
|
6
9
|
const primitives_1 = require("../../common/primitives");
|
|
7
10
|
const route_1 = require("../../route");
|
|
8
11
|
const payments_1 = require("../../vocabulary/payments");
|
|
@@ -86,10 +89,10 @@ exports.socialNextAddressSchema = (0, objects_1.defineComponent)('SocialNextAddr
|
|
|
86
89
|
const networkQuery = zod_1.z.object({ network: primitives_1.network });
|
|
87
90
|
exports.socialReceiveCursorQuery = networkQuery;
|
|
88
91
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
92
|
+
* The caller's cursor and keys. The addresses to watch are
|
|
93
|
+
* `GET /v1/social/me/receive_addresses` (ADR 0021 D9, amended 2026-11-06);
|
|
94
|
+
* `reserved_through` only says how far the cursor went, and the device
|
|
95
|
+
* compares its key with `account_identity_public_key`.
|
|
93
96
|
*/
|
|
94
97
|
exports.socialReceiveCursorSchema = (0, objects_1.defineComponent)('SocialReceiveCursor', zod_1.z
|
|
95
98
|
.object({
|
|
@@ -108,6 +111,58 @@ exports.socialReceiveCursorSchema = (0, objects_1.defineComponent)('SocialReceiv
|
|
|
108
111
|
.describe("The caller's CURRENT identity public key: their DID's `#key-1`, read from Oxy at request time (never cached), as lowercase hex of the key exactly as the DID publishes it (`publicKeyHex`, the compressed secp256k1 key) — the same encoding as `identity_public_key`. Compare the device's key with THIS, not with `identity_public_key`, which only says what the last reservation used. `null` for a keyless (custodial) account."),
|
|
109
112
|
})
|
|
110
113
|
.strict());
|
|
114
|
+
/**
|
|
115
|
+
* The caller's receive addresses after a sync cursor (ADR 0021 D9, amended
|
|
116
|
+
* 2026-11-06). `after` is the `sync_cursor` of the previous answer, `0` (the
|
|
117
|
+
* default) from the start.
|
|
118
|
+
*/
|
|
119
|
+
exports.socialReceiveAddressesQuery = zod_1.z
|
|
120
|
+
.object({
|
|
121
|
+
network: primitives_1.network,
|
|
122
|
+
after: (0, params_1.queryInteger)({ min: 0, max: MAX_DERIVATION_INDEX })
|
|
123
|
+
.optional()
|
|
124
|
+
.describe('The `sync_cursor` of the previous page or sync; absent (or `0`) lists from the first address.'),
|
|
125
|
+
limit: (0, params_1.queryInteger)({ min: 1, max: payments_1.SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX })
|
|
126
|
+
.optional()
|
|
127
|
+
.describe(`At most this many addresses (default ${payments_1.SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT}); a page exceeds it only by addresses sharing its last index.`),
|
|
128
|
+
})
|
|
129
|
+
.strict();
|
|
130
|
+
/**
|
|
131
|
+
* One FairCoin address the gateway handed out in the caller's Peable wallet —
|
|
132
|
+
* for a payment (merchant, seller, invoice, raw intent, one output of a split
|
|
133
|
+
* payment) or an `@username` request — under ANY key the account has had.
|
|
134
|
+
* Addresses are never reused: each is a fresh index of the account's one
|
|
135
|
+
* cursor (ADR 0002, ADR 0021 D5, D9).
|
|
136
|
+
*/
|
|
137
|
+
exports.socialReceiveAddressSchema = (0, objects_1.defineComponent)('SocialReceiveAddress', zod_1.z
|
|
138
|
+
.object({
|
|
139
|
+
address: zod_1.z.string().describe('The FairCoin address.'),
|
|
140
|
+
derivation_index: zod_1.z
|
|
141
|
+
.number()
|
|
142
|
+
.int()
|
|
143
|
+
.positive()
|
|
144
|
+
.describe("Its index in the account's social-receive tree (`deriveSocialReceiveAddress(key, index)`); index 0, the stable default address, is never handed out."),
|
|
145
|
+
identity_public_key: zod_1.z
|
|
146
|
+
.string()
|
|
147
|
+
.nullable()
|
|
148
|
+
.describe("The identity public key the address was derived from, in the encoding of the cursor's `identity_public_key` (lowercase hex of the DID `#key-1` bytes). It may be a key the account has since replaced. `null` only for an address handed out before keys were recorded."),
|
|
149
|
+
network: primitives_1.network,
|
|
150
|
+
created: primitives_1.unixSeconds.describe('When the address was handed out.'),
|
|
151
|
+
})
|
|
152
|
+
.strict());
|
|
153
|
+
exports.socialReceiveAddressesSchema = (0, objects_1.defineComponent)('SocialReceiveAddresses', zod_1.z
|
|
154
|
+
.object({
|
|
155
|
+
addresses: zod_1.z
|
|
156
|
+
.array(exports.socialReceiveAddressSchema)
|
|
157
|
+
.describe('In ascending `derivation_index`, each address once.'),
|
|
158
|
+
has_more: zod_1.z.boolean().describe('More addresses follow `sync_cursor`: ask again with it.'),
|
|
159
|
+
sync_cursor: zod_1.z
|
|
160
|
+
.number()
|
|
161
|
+
.int()
|
|
162
|
+
.nonnegative()
|
|
163
|
+
.describe('Pass as `after` to continue — the highest `derivation_index` in this page, or `after` when the page is empty. Monotonic: an address handed out later always has a higher index, so a wallet that stored it misses nothing by asking from it.'),
|
|
164
|
+
})
|
|
165
|
+
.strict());
|
|
111
166
|
exports.socialPaymentsQuery = networkQuery;
|
|
112
167
|
/**
|
|
113
168
|
* One social payment as the CALLER saw it — the address-free view, and the
|
|
@@ -148,7 +203,7 @@ exports.socialRoutes = [
|
|
|
148
203
|
path: '/v1/social/{username}/next_address',
|
|
149
204
|
tag: 'Social payments',
|
|
150
205
|
summary: 'Reserve an address to pay a person',
|
|
151
|
-
description: "A fresh address of the recipient's, derived from their Oxy identity key. Limited per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`; paying yourself is refused.",
|
|
206
|
+
description: "A fresh address of the recipient's, derived from their Oxy identity key — or the one this sender already holds and has not paid. Limited per sender and per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`, and one handed too many fresh `@username` addresses in the last day 503 `faircoin_capacity_reached`; paying yourself is refused.",
|
|
152
207
|
auth: 'user',
|
|
153
208
|
params: { username: 'The recipient’s Oxy username.' },
|
|
154
209
|
body: exports.socialNextAddressParams,
|
|
@@ -165,6 +220,17 @@ exports.socialRoutes = [
|
|
|
165
220
|
query: exports.socialReceiveCursorQuery,
|
|
166
221
|
response: exports.socialReceiveCursorSchema,
|
|
167
222
|
}),
|
|
223
|
+
(0, route_1.defineRoute)({
|
|
224
|
+
operationId: 'listSocialReceiveAddresses',
|
|
225
|
+
method: 'get',
|
|
226
|
+
path: '/v1/social/me/receive_addresses',
|
|
227
|
+
tag: 'Social payments',
|
|
228
|
+
summary: "List the caller's receive addresses",
|
|
229
|
+
description: "Every FairCoin address handed out in the caller's Peable wallet on `network` — payments and `@username` alike, under every key the account has had — after `after`, in ascending index, for whoever the session acts as (an organization's, when acting as it). The wallet watches exactly this set (ADR 0021 D9). Read-only.",
|
|
230
|
+
auth: 'user',
|
|
231
|
+
query: exports.socialReceiveAddressesQuery,
|
|
232
|
+
response: exports.socialReceiveAddressesSchema,
|
|
233
|
+
}),
|
|
168
234
|
(0, route_1.defineRoute)({
|
|
169
235
|
operationId: 'listSocialPayments',
|
|
170
236
|
method: 'get',
|
|
@@ -134,7 +134,7 @@ exports.ERROR_CODE_DESCRIPTIONS = {
|
|
|
134
134
|
faircoin_price_unavailable: 'No fresh FairCoin price exists right now, so this order cannot be quoted in FAIR. The other payment methods still work; try FairCoin again shortly.',
|
|
135
135
|
faircoin_wallet_missing: "The Peable wallet that receives this payment (the merchant owner's, or the seller's) isn't set up yet, so it cannot be paid in FairCoin. The other payment methods still work.",
|
|
136
136
|
faircoin_network_closed: 'FairCoin payments on this network are not open on this deployment yet. The other payment methods still work.',
|
|
137
|
-
faircoin_capacity_reached: 'Too many FairCoin
|
|
137
|
+
faircoin_capacity_reached: 'Too many FairCoin addresses of this recipient were handed out in the last day without being paid, so no new one is handed out right now. Nothing was reserved. The other payment methods still work; try FairCoin again later.',
|
|
138
138
|
faircoin_amount_too_small: "One seller's share of this order is below the smallest amount the FairCoin network relays, so it cannot be paid in FairCoin. The other payment methods still work.",
|
|
139
139
|
credit_note_exceeds_invoice: "The credit note's amount exceeds what the invoice can still credit.",
|
|
140
140
|
test_clock_unexpected_state: 'The test clock is advancing; wait until it is ready.',
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// contracts are built from. Zod-free, so the wallet and the shared types read
|
|
5
5
|
// them without bundling a schema.
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.SIMULATED_FAIRCOIN_OUTCOMES = exports.ENRICH_MAX_ADDRESSES = exports.ENRICHMENT_KINDS = exports.SOCIAL_PAYMENT_DIRECTIONS = exports.SOCIAL_SOURCE_REF_MAX_LENGTH = exports.SOCIAL_SOURCE_APP_MAX_LENGTH = exports.SETUP_INTENT_CANCELLATION_REASONS = exports.SETUP_INTENT_USAGES = exports.SETUP_INTENT_STATUSES = exports.DISPUTE_EVIDENCE_TEXT_MAX = exports.DISPUTE_FILE_EVIDENCE_FIELDS = exports.DISPUTE_TEXT_EVIDENCE_FIELDS = exports.DISPUTE_REASONS = exports.DISPUTE_STATUSES = exports.SETTLEMENT_STATUSES = exports.REFUND_ORIGINS = exports.REFUND_REASONS = exports.REFUND_STATUSES = exports.CLIENT_ACTION_KINDS = exports.PAYMENT_ERROR_TYPES = exports.PAYMENT_METHOD_TYPES = exports.CARD_RAIL_PAYMENT_METHOD_TYPES = exports.PAYMENT_INTENT_SETUP_FUTURE_USAGES = exports.PAYMENT_INTENT_CAPTURE_METHODS = exports.MERCHANT_CANCELLATION_REASONS = exports.PAYMENT_INTENT_CANCELLATION_REASONS = exports.PAYMENT_INTENT_STATUSES = exports.PAYMENT_INTENT_MAX_EXPIRES_IN_SECONDS = exports.PAYMENT_INTENT_RAILS = void 0;
|
|
7
|
+
exports.SIMULATED_FAIRCOIN_OUTCOMES = exports.SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX = exports.SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT = exports.ENRICH_MAX_ADDRESSES = exports.ENRICHMENT_KINDS = exports.SOCIAL_PAYMENT_DIRECTIONS = exports.SOCIAL_SOURCE_REF_MAX_LENGTH = exports.SOCIAL_SOURCE_APP_MAX_LENGTH = exports.SETUP_INTENT_CANCELLATION_REASONS = exports.SETUP_INTENT_USAGES = exports.SETUP_INTENT_STATUSES = exports.DISPUTE_EVIDENCE_TEXT_MAX = exports.DISPUTE_FILE_EVIDENCE_FIELDS = exports.DISPUTE_TEXT_EVIDENCE_FIELDS = exports.DISPUTE_REASONS = exports.DISPUTE_STATUSES = exports.SETTLEMENT_STATUSES = exports.REFUND_ORIGINS = exports.REFUND_REASONS = exports.REFUND_STATUSES = exports.CLIENT_ACTION_KINDS = exports.PAYMENT_ERROR_TYPES = exports.PAYMENT_METHOD_TYPES = exports.CARD_RAIL_PAYMENT_METHOD_TYPES = exports.PAYMENT_INTENT_SETUP_FUTURE_USAGES = exports.PAYMENT_INTENT_CAPTURE_METHODS = exports.MERCHANT_CANCELLATION_REASONS = exports.PAYMENT_INTENT_CANCELLATION_REASONS = exports.PAYMENT_INTENT_STATUSES = exports.PAYMENT_INTENT_MAX_EXPIRES_IN_SECONDS = exports.PAYMENT_INTENT_RAILS = void 0;
|
|
8
8
|
/**
|
|
9
9
|
* Which rail moves the money (ADR 0001 D1). On the INTENT, not on the merchant:
|
|
10
10
|
* one merchant takes both, and the rail decides which fields mean anything.
|
|
@@ -13,8 +13,8 @@ exports.PAYMENT_INTENT_RAILS = ['faircoin', 'card'];
|
|
|
13
13
|
/**
|
|
14
14
|
* The longest a PaymentIntent created through the API may stay payable before
|
|
15
15
|
* it expires (`expires_in_seconds`): 24 hours. A FairCoin payment holds a
|
|
16
|
-
* reserved address in the recipient's wallet for as long as it is payable,
|
|
17
|
-
*
|
|
16
|
+
* reserved address in the recipient's wallet for as long as it is payable, and
|
|
17
|
+
* the recipient's bound on unpaid addresses looks back over a day (ADR 0021 D9).
|
|
18
18
|
*/
|
|
19
19
|
exports.PAYMENT_INTENT_MAX_EXPIRES_IN_SECONDS = 24 * 60 * 60;
|
|
20
20
|
/**
|
|
@@ -33,17 +33,21 @@ exports.PAYMENT_INTENT_STATUSES = [
|
|
|
33
33
|
'canceled',
|
|
34
34
|
];
|
|
35
35
|
/**
|
|
36
|
-
* Why an intent was cancelled — Stripe's reasons, plus
|
|
37
|
-
* `underpaid` (a transaction paid less than the amount)
|
|
36
|
+
* Why an intent was cancelled — Stripe's reasons, plus three FairCoin-only ones:
|
|
37
|
+
* `underpaid` (a transaction paid less than the amount),
|
|
38
38
|
* `recipient_key_changed` (the recipient's identity key was replaced after the
|
|
39
39
|
* address was reserved, so the address is no longer in the wallet it pays —
|
|
40
40
|
* ADR 0002, amended 2026-11-06; nothing had been broadcast, and the order stays
|
|
41
|
-
* open for a fresh address)
|
|
41
|
+
* open for a fresh address) and `faircoin_network_closed` (the deployment
|
|
42
|
+
* closed the payment's FairCoin network — ADR 0002's gate — before anything was
|
|
43
|
+
* broadcast; the order stays open, and FairCoin on it says the network is
|
|
44
|
+
* closed).
|
|
42
45
|
*/
|
|
43
46
|
exports.PAYMENT_INTENT_CANCELLATION_REASONS = [
|
|
44
47
|
'abandoned',
|
|
45
48
|
'automatic',
|
|
46
49
|
'duplicate',
|
|
50
|
+
'faircoin_network_closed',
|
|
47
51
|
'fraudulent',
|
|
48
52
|
'recipient_key_changed',
|
|
49
53
|
'requested_by_customer',
|
|
@@ -196,6 +200,12 @@ exports.SOCIAL_PAYMENT_DIRECTIONS = ['sent', 'received'];
|
|
|
196
200
|
exports.ENRICHMENT_KINDS = ['merchant', 'user', 'unknown'];
|
|
197
201
|
/** How many addresses one `POST /v1/enrich` resolves (and one social history lists). */
|
|
198
202
|
exports.ENRICH_MAX_ADDRESSES = 50;
|
|
203
|
+
/**
|
|
204
|
+
* One page of `GET /v1/social/me/receive_addresses` (ADR 0021 D9, amended
|
|
205
|
+
* 2026-11-06): the default and the most a wallet may ask for at once.
|
|
206
|
+
*/
|
|
207
|
+
exports.SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT = 500;
|
|
208
|
+
exports.SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX = 1000;
|
|
199
209
|
// ---------------------------------------------------------------------------
|
|
200
210
|
// Test helpers
|
|
201
211
|
// ---------------------------------------------------------------------------
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { defineComponent } from '../../common/objects.js';
|
|
3
|
+
import { queryInteger } from '../../common/params.js';
|
|
4
|
+
/** The highest BIP32 non-hardened child index, `int4`'s ceiling (`schema/valueSets.ts`). */
|
|
5
|
+
const MAX_DERIVATION_INDEX = 2147483647;
|
|
3
6
|
import { network, unixSeconds } from '../../common/primitives.js';
|
|
4
7
|
import { defineRoute } from '../../route.js';
|
|
5
|
-
import { ENRICH_MAX_ADDRESSES, ENRICHMENT_KINDS, SOCIAL_PAYMENT_DIRECTIONS, SOCIAL_SOURCE_APP_MAX_LENGTH, SOCIAL_SOURCE_REF_MAX_LENGTH, } from '../../vocabulary/payments.js';
|
|
8
|
+
import { ENRICH_MAX_ADDRESSES, ENRICHMENT_KINDS, SOCIAL_PAYMENT_DIRECTIONS, SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT, SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX, SOCIAL_SOURCE_APP_MAX_LENGTH, SOCIAL_SOURCE_REF_MAX_LENGTH, } from '../../vocabulary/payments.js';
|
|
6
9
|
/**
|
|
7
10
|
* Social payments (pay a person by `@username`) and transaction enrichment —
|
|
8
11
|
* the wallet's routes, called with the person's own Oxy session. Display-only
|
|
@@ -83,10 +86,10 @@ export const socialNextAddressSchema = defineComponent('SocialNextAddress', z
|
|
|
83
86
|
const networkQuery = z.object({ network });
|
|
84
87
|
export const socialReceiveCursorQuery = networkQuery;
|
|
85
88
|
/**
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
89
|
+
* The caller's cursor and keys. The addresses to watch are
|
|
90
|
+
* `GET /v1/social/me/receive_addresses` (ADR 0021 D9, amended 2026-11-06);
|
|
91
|
+
* `reserved_through` only says how far the cursor went, and the device
|
|
92
|
+
* compares its key with `account_identity_public_key`.
|
|
90
93
|
*/
|
|
91
94
|
export const socialReceiveCursorSchema = defineComponent('SocialReceiveCursor', z
|
|
92
95
|
.object({
|
|
@@ -105,6 +108,58 @@ export const socialReceiveCursorSchema = defineComponent('SocialReceiveCursor',
|
|
|
105
108
|
.describe("The caller's CURRENT identity public key: their DID's `#key-1`, read from Oxy at request time (never cached), as lowercase hex of the key exactly as the DID publishes it (`publicKeyHex`, the compressed secp256k1 key) — the same encoding as `identity_public_key`. Compare the device's key with THIS, not with `identity_public_key`, which only says what the last reservation used. `null` for a keyless (custodial) account."),
|
|
106
109
|
})
|
|
107
110
|
.strict());
|
|
111
|
+
/**
|
|
112
|
+
* The caller's receive addresses after a sync cursor (ADR 0021 D9, amended
|
|
113
|
+
* 2026-11-06). `after` is the `sync_cursor` of the previous answer, `0` (the
|
|
114
|
+
* default) from the start.
|
|
115
|
+
*/
|
|
116
|
+
export const socialReceiveAddressesQuery = z
|
|
117
|
+
.object({
|
|
118
|
+
network,
|
|
119
|
+
after: queryInteger({ min: 0, max: MAX_DERIVATION_INDEX })
|
|
120
|
+
.optional()
|
|
121
|
+
.describe('The `sync_cursor` of the previous page or sync; absent (or `0`) lists from the first address.'),
|
|
122
|
+
limit: queryInteger({ min: 1, max: SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX })
|
|
123
|
+
.optional()
|
|
124
|
+
.describe(`At most this many addresses (default ${SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT}); a page exceeds it only by addresses sharing its last index.`),
|
|
125
|
+
})
|
|
126
|
+
.strict();
|
|
127
|
+
/**
|
|
128
|
+
* One FairCoin address the gateway handed out in the caller's Peable wallet —
|
|
129
|
+
* for a payment (merchant, seller, invoice, raw intent, one output of a split
|
|
130
|
+
* payment) or an `@username` request — under ANY key the account has had.
|
|
131
|
+
* Addresses are never reused: each is a fresh index of the account's one
|
|
132
|
+
* cursor (ADR 0002, ADR 0021 D5, D9).
|
|
133
|
+
*/
|
|
134
|
+
export const socialReceiveAddressSchema = defineComponent('SocialReceiveAddress', z
|
|
135
|
+
.object({
|
|
136
|
+
address: z.string().describe('The FairCoin address.'),
|
|
137
|
+
derivation_index: z
|
|
138
|
+
.number()
|
|
139
|
+
.int()
|
|
140
|
+
.positive()
|
|
141
|
+
.describe("Its index in the account's social-receive tree (`deriveSocialReceiveAddress(key, index)`); index 0, the stable default address, is never handed out."),
|
|
142
|
+
identity_public_key: z
|
|
143
|
+
.string()
|
|
144
|
+
.nullable()
|
|
145
|
+
.describe("The identity public key the address was derived from, in the encoding of the cursor's `identity_public_key` (lowercase hex of the DID `#key-1` bytes). It may be a key the account has since replaced. `null` only for an address handed out before keys were recorded."),
|
|
146
|
+
network,
|
|
147
|
+
created: unixSeconds.describe('When the address was handed out.'),
|
|
148
|
+
})
|
|
149
|
+
.strict());
|
|
150
|
+
export const socialReceiveAddressesSchema = defineComponent('SocialReceiveAddresses', z
|
|
151
|
+
.object({
|
|
152
|
+
addresses: z
|
|
153
|
+
.array(socialReceiveAddressSchema)
|
|
154
|
+
.describe('In ascending `derivation_index`, each address once.'),
|
|
155
|
+
has_more: z.boolean().describe('More addresses follow `sync_cursor`: ask again with it.'),
|
|
156
|
+
sync_cursor: z
|
|
157
|
+
.number()
|
|
158
|
+
.int()
|
|
159
|
+
.nonnegative()
|
|
160
|
+
.describe('Pass as `after` to continue — the highest `derivation_index` in this page, or `after` when the page is empty. Monotonic: an address handed out later always has a higher index, so a wallet that stored it misses nothing by asking from it.'),
|
|
161
|
+
})
|
|
162
|
+
.strict());
|
|
108
163
|
export const socialPaymentsQuery = networkQuery;
|
|
109
164
|
/**
|
|
110
165
|
* One social payment as the CALLER saw it — the address-free view, and the
|
|
@@ -145,7 +200,7 @@ export const socialRoutes = [
|
|
|
145
200
|
path: '/v1/social/{username}/next_address',
|
|
146
201
|
tag: 'Social payments',
|
|
147
202
|
summary: 'Reserve an address to pay a person',
|
|
148
|
-
description: "A fresh address of the recipient's, derived from their Oxy identity key. Limited per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`; paying yourself is refused.",
|
|
203
|
+
description: "A fresh address of the recipient's, derived from their Oxy identity key — or the one this sender already holds and has not paid. Limited per sender and per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`, and one handed too many fresh `@username` addresses in the last day 503 `faircoin_capacity_reached`; paying yourself is refused.",
|
|
149
204
|
auth: 'user',
|
|
150
205
|
params: { username: 'The recipient’s Oxy username.' },
|
|
151
206
|
body: socialNextAddressParams,
|
|
@@ -162,6 +217,17 @@ export const socialRoutes = [
|
|
|
162
217
|
query: socialReceiveCursorQuery,
|
|
163
218
|
response: socialReceiveCursorSchema,
|
|
164
219
|
}),
|
|
220
|
+
defineRoute({
|
|
221
|
+
operationId: 'listSocialReceiveAddresses',
|
|
222
|
+
method: 'get',
|
|
223
|
+
path: '/v1/social/me/receive_addresses',
|
|
224
|
+
tag: 'Social payments',
|
|
225
|
+
summary: "List the caller's receive addresses",
|
|
226
|
+
description: "Every FairCoin address handed out in the caller's Peable wallet on `network` — payments and `@username` alike, under every key the account has had — after `after`, in ascending index, for whoever the session acts as (an organization's, when acting as it). The wallet watches exactly this set (ADR 0021 D9). Read-only.",
|
|
227
|
+
auth: 'user',
|
|
228
|
+
query: socialReceiveAddressesQuery,
|
|
229
|
+
response: socialReceiveAddressesSchema,
|
|
230
|
+
}),
|
|
165
231
|
defineRoute({
|
|
166
232
|
operationId: 'listSocialPayments',
|
|
167
233
|
method: 'get',
|
|
@@ -129,7 +129,7 @@ export const ERROR_CODE_DESCRIPTIONS = {
|
|
|
129
129
|
faircoin_price_unavailable: 'No fresh FairCoin price exists right now, so this order cannot be quoted in FAIR. The other payment methods still work; try FairCoin again shortly.',
|
|
130
130
|
faircoin_wallet_missing: "The Peable wallet that receives this payment (the merchant owner's, or the seller's) isn't set up yet, so it cannot be paid in FairCoin. The other payment methods still work.",
|
|
131
131
|
faircoin_network_closed: 'FairCoin payments on this network are not open on this deployment yet. The other payment methods still work.',
|
|
132
|
-
faircoin_capacity_reached: 'Too many FairCoin
|
|
132
|
+
faircoin_capacity_reached: 'Too many FairCoin addresses of this recipient were handed out in the last day without being paid, so no new one is handed out right now. Nothing was reserved. The other payment methods still work; try FairCoin again later.',
|
|
133
133
|
faircoin_amount_too_small: "One seller's share of this order is below the smallest amount the FairCoin network relays, so it cannot be paid in FairCoin. The other payment methods still work.",
|
|
134
134
|
credit_note_exceeds_invoice: "The credit note's amount exceeds what the invoice can still credit.",
|
|
135
135
|
test_clock_unexpected_state: 'The test clock is advancing; wait until it is ready.',
|
|
@@ -10,8 +10,8 @@ export const PAYMENT_INTENT_RAILS = ['faircoin', 'card'];
|
|
|
10
10
|
/**
|
|
11
11
|
* The longest a PaymentIntent created through the API may stay payable before
|
|
12
12
|
* it expires (`expires_in_seconds`): 24 hours. A FairCoin payment holds a
|
|
13
|
-
* reserved address in the recipient's wallet for as long as it is payable,
|
|
14
|
-
*
|
|
13
|
+
* reserved address in the recipient's wallet for as long as it is payable, and
|
|
14
|
+
* the recipient's bound on unpaid addresses looks back over a day (ADR 0021 D9).
|
|
15
15
|
*/
|
|
16
16
|
export const PAYMENT_INTENT_MAX_EXPIRES_IN_SECONDS = 24 * 60 * 60;
|
|
17
17
|
/**
|
|
@@ -30,17 +30,21 @@ export const PAYMENT_INTENT_STATUSES = [
|
|
|
30
30
|
'canceled',
|
|
31
31
|
];
|
|
32
32
|
/**
|
|
33
|
-
* Why an intent was cancelled — Stripe's reasons, plus
|
|
34
|
-
* `underpaid` (a transaction paid less than the amount)
|
|
33
|
+
* Why an intent was cancelled — Stripe's reasons, plus three FairCoin-only ones:
|
|
34
|
+
* `underpaid` (a transaction paid less than the amount),
|
|
35
35
|
* `recipient_key_changed` (the recipient's identity key was replaced after the
|
|
36
36
|
* address was reserved, so the address is no longer in the wallet it pays —
|
|
37
37
|
* ADR 0002, amended 2026-11-06; nothing had been broadcast, and the order stays
|
|
38
|
-
* open for a fresh address)
|
|
38
|
+
* open for a fresh address) and `faircoin_network_closed` (the deployment
|
|
39
|
+
* closed the payment's FairCoin network — ADR 0002's gate — before anything was
|
|
40
|
+
* broadcast; the order stays open, and FairCoin on it says the network is
|
|
41
|
+
* closed).
|
|
39
42
|
*/
|
|
40
43
|
export const PAYMENT_INTENT_CANCELLATION_REASONS = [
|
|
41
44
|
'abandoned',
|
|
42
45
|
'automatic',
|
|
43
46
|
'duplicate',
|
|
47
|
+
'faircoin_network_closed',
|
|
44
48
|
'fraudulent',
|
|
45
49
|
'recipient_key_changed',
|
|
46
50
|
'requested_by_customer',
|
|
@@ -193,6 +197,12 @@ export const SOCIAL_PAYMENT_DIRECTIONS = ['sent', 'received'];
|
|
|
193
197
|
export const ENRICHMENT_KINDS = ['merchant', 'user', 'unknown'];
|
|
194
198
|
/** How many addresses one `POST /v1/enrich` resolves (and one social history lists). */
|
|
195
199
|
export const ENRICH_MAX_ADDRESSES = 50;
|
|
200
|
+
/**
|
|
201
|
+
* One page of `GET /v1/social/me/receive_addresses` (ADR 0021 D9, amended
|
|
202
|
+
* 2026-11-06): the default and the most a wallet may ask for at once.
|
|
203
|
+
*/
|
|
204
|
+
export const SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT = 500;
|
|
205
|
+
export const SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX = 1000;
|
|
196
206
|
// ---------------------------------------------------------------------------
|
|
197
207
|
// Test helpers
|
|
198
208
|
// ---------------------------------------------------------------------------
|
|
@@ -178,6 +178,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
178
178
|
message: import("zod").ZodString;
|
|
179
179
|
}, import("zod/v4/core").$strict>>;
|
|
180
180
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
181
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
181
182
|
duplicate: "duplicate";
|
|
182
183
|
fraudulent: "fraudulent";
|
|
183
184
|
abandoned: "abandoned";
|
|
@@ -402,6 +403,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
402
403
|
message: import("zod").ZodString;
|
|
403
404
|
}, import("zod/v4/core").$strict>>;
|
|
404
405
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
406
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
405
407
|
duplicate: "duplicate";
|
|
406
408
|
fraudulent: "fraudulent";
|
|
407
409
|
abandoned: "abandoned";
|
|
@@ -607,6 +609,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
607
609
|
message: import("zod").ZodString;
|
|
608
610
|
}, import("zod/v4/core").$strict>>;
|
|
609
611
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
612
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
610
613
|
duplicate: "duplicate";
|
|
611
614
|
fraudulent: "fraudulent";
|
|
612
615
|
abandoned: "abandoned";
|
|
@@ -826,6 +829,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
826
829
|
message: import("zod").ZodString;
|
|
827
830
|
}, import("zod/v4/core").$strict>>;
|
|
828
831
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
832
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
829
833
|
duplicate: "duplicate";
|
|
830
834
|
fraudulent: "fraudulent";
|
|
831
835
|
abandoned: "abandoned";
|
|
@@ -1075,6 +1079,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
1075
1079
|
message: import("zod").ZodString;
|
|
1076
1080
|
}, import("zod/v4/core").$strict>>;
|
|
1077
1081
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
1082
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1078
1083
|
duplicate: "duplicate";
|
|
1079
1084
|
fraudulent: "fraudulent";
|
|
1080
1085
|
abandoned: "abandoned";
|
|
@@ -1278,6 +1283,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
1278
1283
|
message: import("zod").ZodString;
|
|
1279
1284
|
}, import("zod/v4/core").$strict>>;
|
|
1280
1285
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
1286
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1281
1287
|
duplicate: "duplicate";
|
|
1282
1288
|
fraudulent: "fraudulent";
|
|
1283
1289
|
abandoned: "abandoned";
|
|
@@ -1486,6 +1492,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
1486
1492
|
message: import("zod").ZodString;
|
|
1487
1493
|
}, import("zod/v4/core").$strict>>;
|
|
1488
1494
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
1495
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1489
1496
|
duplicate: "duplicate";
|
|
1490
1497
|
fraudulent: "fraudulent";
|
|
1491
1498
|
abandoned: "abandoned";
|
|
@@ -1687,6 +1694,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
1687
1694
|
message: import("zod").ZodString;
|
|
1688
1695
|
}, import("zod/v4/core").$strict>>;
|
|
1689
1696
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
1697
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1690
1698
|
duplicate: "duplicate";
|
|
1691
1699
|
fraudulent: "fraudulent";
|
|
1692
1700
|
abandoned: "abandoned";
|
|
@@ -1888,6 +1896,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
1888
1896
|
message: import("zod").ZodString;
|
|
1889
1897
|
}, import("zod/v4/core").$strict>>;
|
|
1890
1898
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
1899
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1891
1900
|
duplicate: "duplicate";
|
|
1892
1901
|
fraudulent: "fraudulent";
|
|
1893
1902
|
abandoned: "abandoned";
|
|
@@ -3703,7 +3712,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
3703
3712
|
readonly path: "/v1/social/{username}/next_address";
|
|
3704
3713
|
readonly tag: "Social payments";
|
|
3705
3714
|
readonly summary: "Reserve an address to pay a person";
|
|
3706
|
-
readonly description: "A fresh address of the recipient's, derived from their Oxy identity key. Limited per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`; paying yourself is refused.";
|
|
3715
|
+
readonly description: "A fresh address of the recipient's, derived from their Oxy identity key — or the one this sender already holds and has not paid. Limited per sender and per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`, and one handed too many fresh `@username` addresses in the last day 503 `faircoin_capacity_reached`; paying yourself is refused.";
|
|
3707
3716
|
readonly auth: "user";
|
|
3708
3717
|
readonly params: {
|
|
3709
3718
|
readonly username: "The recipient’s Oxy username.";
|
|
@@ -3741,6 +3750,36 @@ export declare const paymentsRoutes: readonly [{
|
|
|
3741
3750
|
identity_public_key: import("zod").ZodNullable<import("zod").ZodString>;
|
|
3742
3751
|
account_identity_public_key: import("zod").ZodNullable<import("zod").ZodString>;
|
|
3743
3752
|
}, import("zod/v4/core").$strict>;
|
|
3753
|
+
}, {
|
|
3754
|
+
readonly operationId: "listSocialReceiveAddresses";
|
|
3755
|
+
readonly method: "get";
|
|
3756
|
+
readonly path: "/v1/social/me/receive_addresses";
|
|
3757
|
+
readonly tag: "Social payments";
|
|
3758
|
+
readonly summary: "List the caller's receive addresses";
|
|
3759
|
+
readonly description: "Every FairCoin address handed out in the caller's Peable wallet on `network` — payments and `@username` alike, under every key the account has had — after `after`, in ascending index, for whoever the session acts as (an organization's, when acting as it). The wallet watches exactly this set (ADR 0021 D9). Read-only.";
|
|
3760
|
+
readonly auth: "user";
|
|
3761
|
+
readonly query: import("zod").ZodObject<{
|
|
3762
|
+
network: import("zod").ZodEnum<{
|
|
3763
|
+
mainnet: "mainnet";
|
|
3764
|
+
testnet: "testnet";
|
|
3765
|
+
}>;
|
|
3766
|
+
after: import("zod").ZodOptional<import("zod").ZodPipe<import("zod").ZodPipe<import("zod").ZodUnion<readonly [import("zod").ZodNumber, import("zod").ZodString]>, import("zod").ZodTransform<number, string | number>>, import("zod").ZodNumber>>;
|
|
3767
|
+
limit: import("zod").ZodOptional<import("zod").ZodPipe<import("zod").ZodPipe<import("zod").ZodUnion<readonly [import("zod").ZodNumber, import("zod").ZodString]>, import("zod").ZodTransform<number, string | number>>, import("zod").ZodNumber>>;
|
|
3768
|
+
}, import("zod/v4/core").$strict>;
|
|
3769
|
+
readonly response: import("zod").ZodObject<{
|
|
3770
|
+
addresses: import("zod").ZodArray<import("zod").ZodObject<{
|
|
3771
|
+
address: import("zod").ZodString;
|
|
3772
|
+
derivation_index: import("zod").ZodNumber;
|
|
3773
|
+
identity_public_key: import("zod").ZodNullable<import("zod").ZodString>;
|
|
3774
|
+
network: import("zod").ZodEnum<{
|
|
3775
|
+
mainnet: "mainnet";
|
|
3776
|
+
testnet: "testnet";
|
|
3777
|
+
}>;
|
|
3778
|
+
created: import("zod").ZodNumber;
|
|
3779
|
+
}, import("zod/v4/core").$strict>>;
|
|
3780
|
+
has_more: import("zod").ZodBoolean;
|
|
3781
|
+
sync_cursor: import("zod").ZodNumber;
|
|
3782
|
+
}, import("zod/v4/core").$strict>;
|
|
3744
3783
|
}, {
|
|
3745
3784
|
readonly operationId: "listSocialPayments";
|
|
3746
3785
|
readonly method: "get";
|
|
@@ -3911,6 +3950,7 @@ export declare const paymentsRoutes: readonly [{
|
|
|
3911
3950
|
message: import("zod").ZodString;
|
|
3912
3951
|
}, import("zod/v4/core").$strict>>;
|
|
3913
3952
|
cancellation_reason: import("zod").ZodNullable<import("zod").ZodEnum<{
|
|
3953
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
3914
3954
|
duplicate: "duplicate";
|
|
3915
3955
|
fraudulent: "fraudulent";
|
|
3916
3956
|
abandoned: "abandoned";
|
|
@@ -262,6 +262,7 @@ export declare const paymentIntentSchema: z.ZodObject<{
|
|
|
262
262
|
message: z.ZodString;
|
|
263
263
|
}, z.core.$strict>>;
|
|
264
264
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
265
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
265
266
|
duplicate: "duplicate";
|
|
266
267
|
fraudulent: "fraudulent";
|
|
267
268
|
abandoned: "abandoned";
|
|
@@ -770,6 +771,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
770
771
|
message: z.ZodString;
|
|
771
772
|
}, z.core.$strict>>;
|
|
772
773
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
774
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
773
775
|
duplicate: "duplicate";
|
|
774
776
|
fraudulent: "fraudulent";
|
|
775
777
|
abandoned: "abandoned";
|
|
@@ -994,6 +996,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
994
996
|
message: z.ZodString;
|
|
995
997
|
}, z.core.$strict>>;
|
|
996
998
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
999
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
997
1000
|
duplicate: "duplicate";
|
|
998
1001
|
fraudulent: "fraudulent";
|
|
999
1002
|
abandoned: "abandoned";
|
|
@@ -1199,6 +1202,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
1199
1202
|
message: z.ZodString;
|
|
1200
1203
|
}, z.core.$strict>>;
|
|
1201
1204
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
1205
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1202
1206
|
duplicate: "duplicate";
|
|
1203
1207
|
fraudulent: "fraudulent";
|
|
1204
1208
|
abandoned: "abandoned";
|
|
@@ -1418,6 +1422,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
1418
1422
|
message: z.ZodString;
|
|
1419
1423
|
}, z.core.$strict>>;
|
|
1420
1424
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
1425
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1421
1426
|
duplicate: "duplicate";
|
|
1422
1427
|
fraudulent: "fraudulent";
|
|
1423
1428
|
abandoned: "abandoned";
|
|
@@ -1667,6 +1672,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
1667
1672
|
message: z.ZodString;
|
|
1668
1673
|
}, z.core.$strict>>;
|
|
1669
1674
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
1675
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1670
1676
|
duplicate: "duplicate";
|
|
1671
1677
|
fraudulent: "fraudulent";
|
|
1672
1678
|
abandoned: "abandoned";
|
|
@@ -1870,6 +1876,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
1870
1876
|
message: z.ZodString;
|
|
1871
1877
|
}, z.core.$strict>>;
|
|
1872
1878
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
1879
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
1873
1880
|
duplicate: "duplicate";
|
|
1874
1881
|
fraudulent: "fraudulent";
|
|
1875
1882
|
abandoned: "abandoned";
|
|
@@ -2078,6 +2085,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
2078
2085
|
message: z.ZodString;
|
|
2079
2086
|
}, z.core.$strict>>;
|
|
2080
2087
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
2088
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
2081
2089
|
duplicate: "duplicate";
|
|
2082
2090
|
fraudulent: "fraudulent";
|
|
2083
2091
|
abandoned: "abandoned";
|
|
@@ -2279,6 +2287,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
2279
2287
|
message: z.ZodString;
|
|
2280
2288
|
}, z.core.$strict>>;
|
|
2281
2289
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
2290
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
2282
2291
|
duplicate: "duplicate";
|
|
2283
2292
|
fraudulent: "fraudulent";
|
|
2284
2293
|
abandoned: "abandoned";
|
|
@@ -2480,6 +2489,7 @@ export declare const paymentIntentRoutes: readonly [{
|
|
|
2480
2489
|
message: z.ZodString;
|
|
2481
2490
|
}, z.core.$strict>>;
|
|
2482
2491
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
2492
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
2483
2493
|
duplicate: "duplicate";
|
|
2484
2494
|
fraudulent: "fraudulent";
|
|
2485
2495
|
abandoned: "abandoned";
|
|
@@ -68,10 +68,10 @@ export declare const socialReceiveCursorQuery: z.ZodObject<{
|
|
|
68
68
|
}, z.core.$strip>;
|
|
69
69
|
export type SocialReceiveCursorParams = z.input<typeof socialReceiveCursorQuery>;
|
|
70
70
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
71
|
+
* The caller's cursor and keys. The addresses to watch are
|
|
72
|
+
* `GET /v1/social/me/receive_addresses` (ADR 0021 D9, amended 2026-11-06);
|
|
73
|
+
* `reserved_through` only says how far the cursor went, and the device
|
|
74
|
+
* compares its key with `account_identity_public_key`.
|
|
75
75
|
*/
|
|
76
76
|
export declare const socialReceiveCursorSchema: z.ZodObject<{
|
|
77
77
|
reserved_through: z.ZodNumber;
|
|
@@ -79,6 +79,53 @@ export declare const socialReceiveCursorSchema: z.ZodObject<{
|
|
|
79
79
|
account_identity_public_key: z.ZodNullable<z.ZodString>;
|
|
80
80
|
}, z.core.$strict>;
|
|
81
81
|
export type SocialReceiveCursorResponse = z.output<typeof socialReceiveCursorSchema>;
|
|
82
|
+
/**
|
|
83
|
+
* The caller's receive addresses after a sync cursor (ADR 0021 D9, amended
|
|
84
|
+
* 2026-11-06). `after` is the `sync_cursor` of the previous answer, `0` (the
|
|
85
|
+
* default) from the start.
|
|
86
|
+
*/
|
|
87
|
+
export declare const socialReceiveAddressesQuery: z.ZodObject<{
|
|
88
|
+
network: z.ZodEnum<{
|
|
89
|
+
mainnet: "mainnet";
|
|
90
|
+
testnet: "testnet";
|
|
91
|
+
}>;
|
|
92
|
+
after: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>, z.ZodNumber>>;
|
|
93
|
+
limit: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>, z.ZodNumber>>;
|
|
94
|
+
}, z.core.$strict>;
|
|
95
|
+
export type SocialReceiveAddressesParams = z.input<typeof socialReceiveAddressesQuery>;
|
|
96
|
+
/**
|
|
97
|
+
* One FairCoin address the gateway handed out in the caller's Peable wallet —
|
|
98
|
+
* for a payment (merchant, seller, invoice, raw intent, one output of a split
|
|
99
|
+
* payment) or an `@username` request — under ANY key the account has had.
|
|
100
|
+
* Addresses are never reused: each is a fresh index of the account's one
|
|
101
|
+
* cursor (ADR 0002, ADR 0021 D5, D9).
|
|
102
|
+
*/
|
|
103
|
+
export declare const socialReceiveAddressSchema: z.ZodObject<{
|
|
104
|
+
address: z.ZodString;
|
|
105
|
+
derivation_index: z.ZodNumber;
|
|
106
|
+
identity_public_key: z.ZodNullable<z.ZodString>;
|
|
107
|
+
network: z.ZodEnum<{
|
|
108
|
+
mainnet: "mainnet";
|
|
109
|
+
testnet: "testnet";
|
|
110
|
+
}>;
|
|
111
|
+
created: z.ZodNumber;
|
|
112
|
+
}, z.core.$strict>;
|
|
113
|
+
export type SocialReceiveAddress = z.output<typeof socialReceiveAddressSchema>;
|
|
114
|
+
export declare const socialReceiveAddressesSchema: z.ZodObject<{
|
|
115
|
+
addresses: z.ZodArray<z.ZodObject<{
|
|
116
|
+
address: z.ZodString;
|
|
117
|
+
derivation_index: z.ZodNumber;
|
|
118
|
+
identity_public_key: z.ZodNullable<z.ZodString>;
|
|
119
|
+
network: z.ZodEnum<{
|
|
120
|
+
mainnet: "mainnet";
|
|
121
|
+
testnet: "testnet";
|
|
122
|
+
}>;
|
|
123
|
+
created: z.ZodNumber;
|
|
124
|
+
}, z.core.$strict>>;
|
|
125
|
+
has_more: z.ZodBoolean;
|
|
126
|
+
sync_cursor: z.ZodNumber;
|
|
127
|
+
}, z.core.$strict>;
|
|
128
|
+
export type SocialReceiveAddressesResponse = z.output<typeof socialReceiveAddressesSchema>;
|
|
82
129
|
export declare const socialPaymentsQuery: z.ZodObject<{
|
|
83
130
|
network: z.ZodEnum<{
|
|
84
131
|
mainnet: "mainnet";
|
|
@@ -166,7 +213,7 @@ export declare const socialRoutes: readonly [{
|
|
|
166
213
|
readonly path: "/v1/social/{username}/next_address";
|
|
167
214
|
readonly tag: "Social payments";
|
|
168
215
|
readonly summary: "Reserve an address to pay a person";
|
|
169
|
-
readonly description: "A fresh address of the recipient's, derived from their Oxy identity key. Limited per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`; paying yourself is refused.";
|
|
216
|
+
readonly description: "A fresh address of the recipient's, derived from their Oxy identity key — or the one this sender already holds and has not paid. Limited per sender and per (sender, recipient) pair; a recipient without an identity answers 409 `keyless_recipient`, and one handed too many fresh `@username` addresses in the last day 503 `faircoin_capacity_reached`; paying yourself is refused.";
|
|
170
217
|
readonly auth: "user";
|
|
171
218
|
readonly params: {
|
|
172
219
|
readonly username: "The recipient’s Oxy username.";
|
|
@@ -204,6 +251,36 @@ export declare const socialRoutes: readonly [{
|
|
|
204
251
|
identity_public_key: z.ZodNullable<z.ZodString>;
|
|
205
252
|
account_identity_public_key: z.ZodNullable<z.ZodString>;
|
|
206
253
|
}, z.core.$strict>;
|
|
254
|
+
}, {
|
|
255
|
+
readonly operationId: "listSocialReceiveAddresses";
|
|
256
|
+
readonly method: "get";
|
|
257
|
+
readonly path: "/v1/social/me/receive_addresses";
|
|
258
|
+
readonly tag: "Social payments";
|
|
259
|
+
readonly summary: "List the caller's receive addresses";
|
|
260
|
+
readonly description: "Every FairCoin address handed out in the caller's Peable wallet on `network` — payments and `@username` alike, under every key the account has had — after `after`, in ascending index, for whoever the session acts as (an organization's, when acting as it). The wallet watches exactly this set (ADR 0021 D9). Read-only.";
|
|
261
|
+
readonly auth: "user";
|
|
262
|
+
readonly query: z.ZodObject<{
|
|
263
|
+
network: z.ZodEnum<{
|
|
264
|
+
mainnet: "mainnet";
|
|
265
|
+
testnet: "testnet";
|
|
266
|
+
}>;
|
|
267
|
+
after: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>, z.ZodNumber>>;
|
|
268
|
+
limit: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>, z.ZodTransform<number, string | number>>, z.ZodNumber>>;
|
|
269
|
+
}, z.core.$strict>;
|
|
270
|
+
readonly response: z.ZodObject<{
|
|
271
|
+
addresses: z.ZodArray<z.ZodObject<{
|
|
272
|
+
address: z.ZodString;
|
|
273
|
+
derivation_index: z.ZodNumber;
|
|
274
|
+
identity_public_key: z.ZodNullable<z.ZodString>;
|
|
275
|
+
network: z.ZodEnum<{
|
|
276
|
+
mainnet: "mainnet";
|
|
277
|
+
testnet: "testnet";
|
|
278
|
+
}>;
|
|
279
|
+
created: z.ZodNumber;
|
|
280
|
+
}, z.core.$strict>>;
|
|
281
|
+
has_more: z.ZodBoolean;
|
|
282
|
+
sync_cursor: z.ZodNumber;
|
|
283
|
+
}, z.core.$strict>;
|
|
207
284
|
}, {
|
|
208
285
|
readonly operationId: "listSocialPayments";
|
|
209
286
|
readonly method: "get";
|
|
@@ -120,6 +120,7 @@ export declare const paymentIntentTestHelperRoutes: readonly [{
|
|
|
120
120
|
message: z.ZodString;
|
|
121
121
|
}, z.core.$strict>>;
|
|
122
122
|
cancellation_reason: z.ZodNullable<z.ZodEnum<{
|
|
123
|
+
faircoin_network_closed: "faircoin_network_closed";
|
|
123
124
|
duplicate: "duplicate";
|
|
124
125
|
fraudulent: "fraudulent";
|
|
125
126
|
abandoned: "abandoned";
|
|
@@ -108,7 +108,7 @@ export declare const ERROR_CODE_DESCRIPTIONS: {
|
|
|
108
108
|
readonly faircoin_price_unavailable: "No fresh FairCoin price exists right now, so this order cannot be quoted in FAIR. The other payment methods still work; try FairCoin again shortly.";
|
|
109
109
|
readonly faircoin_wallet_missing: "The Peable wallet that receives this payment (the merchant owner's, or the seller's) isn't set up yet, so it cannot be paid in FairCoin. The other payment methods still work.";
|
|
110
110
|
readonly faircoin_network_closed: "FairCoin payments on this network are not open on this deployment yet. The other payment methods still work.";
|
|
111
|
-
readonly faircoin_capacity_reached: "Too many FairCoin
|
|
111
|
+
readonly faircoin_capacity_reached: "Too many FairCoin addresses of this recipient were handed out in the last day without being paid, so no new one is handed out right now. Nothing was reserved. The other payment methods still work; try FairCoin again later.";
|
|
112
112
|
readonly faircoin_amount_too_small: "One seller's share of this order is below the smallest amount the FairCoin network relays, so it cannot be paid in FairCoin. The other payment methods still work.";
|
|
113
113
|
readonly credit_note_exceeds_invoice: "The credit note's amount exceeds what the invoice can still credit.";
|
|
114
114
|
readonly test_clock_unexpected_state: "The test clock is advancing; wait until it is ready.";
|
|
@@ -7,8 +7,8 @@ export type PaymentIntentRail = (typeof PAYMENT_INTENT_RAILS)[number];
|
|
|
7
7
|
/**
|
|
8
8
|
* The longest a PaymentIntent created through the API may stay payable before
|
|
9
9
|
* it expires (`expires_in_seconds`): 24 hours. A FairCoin payment holds a
|
|
10
|
-
* reserved address in the recipient's wallet for as long as it is payable,
|
|
11
|
-
*
|
|
10
|
+
* reserved address in the recipient's wallet for as long as it is payable, and
|
|
11
|
+
* the recipient's bound on unpaid addresses looks back over a day (ADR 0021 D9).
|
|
12
12
|
*/
|
|
13
13
|
export declare const PAYMENT_INTENT_MAX_EXPIRES_IN_SECONDS: number;
|
|
14
14
|
/**
|
|
@@ -20,14 +20,17 @@ export declare const PAYMENT_INTENT_MAX_EXPIRES_IN_SECONDS: number;
|
|
|
20
20
|
export declare const PAYMENT_INTENT_STATUSES: readonly ["requires_payment_method", "requires_confirmation", "requires_action", "processing", "requires_capture", "succeeded", "canceled"];
|
|
21
21
|
export type PaymentIntentStatus = (typeof PAYMENT_INTENT_STATUSES)[number];
|
|
22
22
|
/**
|
|
23
|
-
* Why an intent was cancelled — Stripe's reasons, plus
|
|
24
|
-
* `underpaid` (a transaction paid less than the amount)
|
|
23
|
+
* Why an intent was cancelled — Stripe's reasons, plus three FairCoin-only ones:
|
|
24
|
+
* `underpaid` (a transaction paid less than the amount),
|
|
25
25
|
* `recipient_key_changed` (the recipient's identity key was replaced after the
|
|
26
26
|
* address was reserved, so the address is no longer in the wallet it pays —
|
|
27
27
|
* ADR 0002, amended 2026-11-06; nothing had been broadcast, and the order stays
|
|
28
|
-
* open for a fresh address)
|
|
28
|
+
* open for a fresh address) and `faircoin_network_closed` (the deployment
|
|
29
|
+
* closed the payment's FairCoin network — ADR 0002's gate — before anything was
|
|
30
|
+
* broadcast; the order stays open, and FairCoin on it says the network is
|
|
31
|
+
* closed).
|
|
29
32
|
*/
|
|
30
|
-
export declare const PAYMENT_INTENT_CANCELLATION_REASONS: readonly ["abandoned", "automatic", "duplicate", "fraudulent", "recipient_key_changed", "requested_by_customer", "underpaid"];
|
|
33
|
+
export declare const PAYMENT_INTENT_CANCELLATION_REASONS: readonly ["abandoned", "automatic", "duplicate", "faircoin_network_closed", "fraudulent", "recipient_key_changed", "requested_by_customer", "underpaid"];
|
|
31
34
|
export type PaymentIntentCancellationReason = (typeof PAYMENT_INTENT_CANCELLATION_REASONS)[number];
|
|
32
35
|
/** The reasons a MERCHANT may give `POST /v1/payment_intents/:id/cancel`. */
|
|
33
36
|
export declare const MERCHANT_CANCELLATION_REASONS: readonly ["abandoned", "duplicate", "fraudulent", "requested_by_customer"];
|
|
@@ -119,6 +122,12 @@ export declare const ENRICHMENT_KINDS: readonly ["merchant", "user", "unknown"];
|
|
|
119
122
|
export type EnrichmentKind = (typeof ENRICHMENT_KINDS)[number];
|
|
120
123
|
/** How many addresses one `POST /v1/enrich` resolves (and one social history lists). */
|
|
121
124
|
export declare const ENRICH_MAX_ADDRESSES = 50;
|
|
125
|
+
/**
|
|
126
|
+
* One page of `GET /v1/social/me/receive_addresses` (ADR 0021 D9, amended
|
|
127
|
+
* 2026-11-06): the default and the most a wallet may ask for at once.
|
|
128
|
+
*/
|
|
129
|
+
export declare const SOCIAL_RECEIVE_ADDRESSES_PAGE_DEFAULT = 500;
|
|
130
|
+
export declare const SOCIAL_RECEIVE_ADDRESSES_PAGE_MAX = 1000;
|
|
122
131
|
/**
|
|
123
132
|
* What `simulate_faircoin_payment` pretends the payer did: `settled` paid the
|
|
124
133
|
* full amount (`processing` → `succeeded`); `underpaid` sent less
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peable.to/contracts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "The Peable wire, declared once: Zod contracts of every public route, the OpenAPI 3.1 generator and the closed value sets (ADR 0014 D5).",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|