@fun-xyz/fiat-contract 0.24.0 → 0.25.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 +20 -13
- package/dist/{chunk-IPOPANXS.mjs → chunk-LHCED3AP.mjs} +2 -2
- package/dist/{chunk-5UEPWL7B.mjs → chunk-WEXD7UEE.mjs} +1 -1
- package/dist/index.js +13 -4
- package/dist/index.mjs +14 -5
- package/dist/routing.d.ts +24 -9
- package/dist/routing.mjs +1 -1
- package/dist/schemas.d.ts +2 -1
- package/dist/table.js +1 -1
- package/dist/table.mjs +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -133,31 +133,38 @@ cause is unknown. Refetch the table at `expiresAt`, on `refreshLimits: true`, an
|
|
|
133
133
|
a `REQUOTE`. The schemas hold the table's invariants: each method once, sorted, non-overlapping
|
|
134
134
|
intervals, at least one provider each and none twice, and a reason only on an empty method.
|
|
135
135
|
|
|
136
|
-
`ROUTING_ENDPOINTS.quote` (`POST /fiat/routing/quote`) takes the `POST /fiat/quote` body
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
136
|
+
`ROUTING_ENDPOINTS.quote` (`POST /fiat/routing/quote`) takes the `POST /fiat/quote` body
|
|
137
|
+
(`FiatRoutingQuoteTerms`), never `routingOverrides`, plus one of two forms:
|
|
138
|
+
|
|
139
|
+
- `providers`: the interval's providers, best first. The backend prices them in order, falls
|
|
140
|
+
through on the refusals marked "next provider" below, and answers the first that prices or the
|
|
141
|
+
last provider's refusal.
|
|
142
|
+
- `provider`: one provider only. The client falls through itself.
|
|
143
|
+
|
|
144
|
+
It answers the same `FiatStepResponse`, whose `provider` names the one that priced. A refusal is a
|
|
145
|
+
`FiatRoutingQuoteErrorBody`, and it decides whether the next provider may still price:
|
|
140
146
|
|
|
141
147
|
| Status | `errorCode` | Then |
|
|
142
148
|
| --- | --- | --- |
|
|
143
|
-
| 404 | `FiatNoRouteError`, `reason` `NO_CANDIDATE`, `PROVIDER_DECLINED`, `PROVIDER_OUTAGE` or `KYC_REJECTED` |
|
|
144
|
-
| 400 | `FiatNoRouteError`, `reason: USER_LIMIT`, `code: LIMITS_EXCEEDED`, `recovery: REQUOTE` |
|
|
145
|
-
| 400 | `FiatAmountBelowMinimumError` (`minFiatAmount`) or `FiatAmountAboveMaximumError` (`maxFiatAmount`) |
|
|
149
|
+
| 404 | `FiatNoRouteError`, `reason` `NO_CANDIDATE`, `PROVIDER_DECLINED`, `PROVIDER_OUTAGE` or `KYC_REJECTED` | next provider |
|
|
150
|
+
| 400 | `FiatNoRouteError`, `reason: USER_LIMIT`, `code: LIMITS_EXCEEDED`, `recovery: REQUOTE` | next provider |
|
|
151
|
+
| 400 | `FiatAmountBelowMinimumError` (`minFiatAmount`) or `FiatAmountAboveMaximumError` (`maxFiatAmount`) | next provider |
|
|
146
152
|
| 400 | `InvalidParameterError`: a bad request, an asset Fun cannot deliver, or no verified email | stop |
|
|
147
153
|
| 401, 5xx | any other: a missing or invalid identity assertion, or a server error | stop |
|
|
148
154
|
|
|
149
|
-
Every fall-through refusal is
|
|
150
|
-
|
|
151
|
-
|
|
155
|
+
Every fall-through refusal is that provider's alone, because each attempt prices only one provider:
|
|
156
|
+
`KYC_REJECTED` there means that provider refused the buyer's identity, not every provider. With no
|
|
157
|
+
provider left in the interval, refetch the table. The table route refuses with a
|
|
152
158
|
`FiatRoutingTableErrorBody`: a 429 `TooManyRequestsError` with `retryAfterSeconds` when the
|
|
153
159
|
per-login budget is spent, or a 400 or 5xx as above. The quote route has no rate limit of its own.
|
|
154
160
|
|
|
155
161
|
Both routes take geo under the `POST /fiat/quote` rules: a known `CountryCode`, a `UsStateCode`
|
|
156
162
|
region for a US buyer, and an empty `region` or `ip` read as absent. The quote route's `geo` is the
|
|
157
163
|
Fun geo endpoint's response forwarded as is. The request schemas are strict like every schema here,
|
|
158
|
-
so a client sends only the declared keys and no blank strings. `provider`
|
|
159
|
-
providers the backend routes (`RoutingProvider`)
|
|
160
|
-
replaces it for each provider that
|
|
164
|
+
so a client sends only the declared keys and no blank strings. `provider` and each `providers`
|
|
165
|
+
entry are one of the five providers the backend routes (`RoutingProvider`), `providers` with no
|
|
166
|
+
duplicates. The quote route is temporary: `POST /fiat/next` replaces it for each provider that
|
|
167
|
+
moves there.
|
|
161
168
|
|
|
162
169
|
**MoonPay (`./moonpay`).** MoonPay runs on the shared `POST /fiat/next` (`MOONPAY_ENDPOINTS.next`).
|
|
163
170
|
Every `/next` body is a `FiatNextRequest`: `provider`, `geo` (a `FiatGeo`, the geo endpoint's
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.
|
|
2
|
+
var version = "0.25.0";
|
|
3
3
|
|
|
4
4
|
// src/table.ts
|
|
5
5
|
var TABLE_VERSION = version;
|
|
@@ -514,4 +514,4 @@ export {
|
|
|
514
514
|
tableEntry,
|
|
515
515
|
isTerminal
|
|
516
516
|
};
|
|
517
|
-
//# sourceMappingURL=chunk-
|
|
517
|
+
//# sourceMappingURL=chunk-LHCED3AP.mjs.map
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ __export(index_exports, {
|
|
|
47
47
|
FiatProviderSchema: () => FiatProviderSchema,
|
|
48
48
|
FiatRoutingQuoteErrorBodySchema: () => FiatRoutingQuoteErrorBodySchema,
|
|
49
49
|
FiatRoutingQuoteRequestSchema: () => FiatRoutingQuoteRequestSchema,
|
|
50
|
+
FiatRoutingQuoteTermsSchema: () => FiatRoutingQuoteTermsSchema,
|
|
50
51
|
FiatRoutingTableErrorBodySchema: () => FiatRoutingTableErrorBodySchema,
|
|
51
52
|
FiatRoutingTableQuerySchema: () => FiatRoutingTableQuerySchema,
|
|
52
53
|
FiatRoutingTableResponseSchema: () => FiatRoutingTableResponseSchema,
|
|
@@ -1088,8 +1089,7 @@ var $routingTableResponse = obj({
|
|
|
1088
1089
|
methods: import_zod.z.array($routingTableMethod).refine((methods) => hasUniqueIds(methods.map((entry) => entry.method)), "each method is listed once")
|
|
1089
1090
|
});
|
|
1090
1091
|
var FiatRoutingTableResponseSchema = $routingTableResponse;
|
|
1091
|
-
var $
|
|
1092
|
-
provider: $routingProvider,
|
|
1092
|
+
var $routingQuoteTermsShape = {
|
|
1093
1093
|
fiatCurrency: import_zod.z.enum(FIAT_CURRENCY_CODES),
|
|
1094
1094
|
fiatAmount: $decimalAmount.refine((amount) => Number(amount) > 0, "must be positive"),
|
|
1095
1095
|
cryptoCurrencyCode: $nonBlank,
|
|
@@ -1100,7 +1100,16 @@ var $routingQuoteRequest = obj({
|
|
|
1100
1100
|
{ message: US_REGION_REQUIRED, path: ["region"] }
|
|
1101
1101
|
),
|
|
1102
1102
|
prepareSessionAuth: import_zod.z.boolean().optional()
|
|
1103
|
-
}
|
|
1103
|
+
};
|
|
1104
|
+
var $routingQuoteTerms = obj($routingQuoteTermsShape);
|
|
1105
|
+
var FiatRoutingQuoteTermsSchema = $routingQuoteTerms;
|
|
1106
|
+
var $routingQuoteRequest = import_zod.z.union([
|
|
1107
|
+
obj({
|
|
1108
|
+
...$routingQuoteTermsShape,
|
|
1109
|
+
providers: import_zod.z.array($routingProvider).min(1).refine((providers) => hasUniqueIds(providers), "each provider is listed once")
|
|
1110
|
+
}),
|
|
1111
|
+
obj({ ...$routingQuoteTermsShape, provider: $routingProvider })
|
|
1112
|
+
]);
|
|
1104
1113
|
var FiatRoutingQuoteRequestSchema = $routingQuoteRequest;
|
|
1105
1114
|
var $routingServiceableRange = obj({ min: $money, max: $money, userMax: $money.nullable().optional() });
|
|
1106
1115
|
var $noRouteFields = {
|
|
@@ -1200,7 +1209,7 @@ var $stepResponse = import_zod.z.union([$providerBoundStepResponse, $blockedStep
|
|
|
1200
1209
|
var FiatStepResponseSchema = $stepResponse;
|
|
1201
1210
|
|
|
1202
1211
|
// package.json
|
|
1203
|
-
var version = "0.
|
|
1212
|
+
var version = "0.25.0";
|
|
1204
1213
|
|
|
1205
1214
|
// src/table.ts
|
|
1206
1215
|
var TABLE_VERSION = version;
|
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
tableEntry,
|
|
13
13
|
unofferedEndpoints,
|
|
14
14
|
unreachableStates
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-LHCED3AP.mjs";
|
|
16
16
|
import {
|
|
17
17
|
MOONPAY_ENDPOINTS
|
|
18
18
|
} from "./chunk-T5JAYOWY.mjs";
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-CRNKRIKR.mjs";
|
|
25
25
|
import {
|
|
26
26
|
ROUTING_ENDPOINTS
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-WEXD7UEE.mjs";
|
|
28
28
|
|
|
29
29
|
// src/codes.ts
|
|
30
30
|
var US_STATE_CODES = [
|
|
@@ -953,8 +953,7 @@ var $routingTableResponse = obj({
|
|
|
953
953
|
methods: z.array($routingTableMethod).refine((methods) => hasUniqueIds(methods.map((entry) => entry.method)), "each method is listed once")
|
|
954
954
|
});
|
|
955
955
|
var FiatRoutingTableResponseSchema = $routingTableResponse;
|
|
956
|
-
var $
|
|
957
|
-
provider: $routingProvider,
|
|
956
|
+
var $routingQuoteTermsShape = {
|
|
958
957
|
fiatCurrency: z.enum(FIAT_CURRENCY_CODES),
|
|
959
958
|
fiatAmount: $decimalAmount.refine((amount) => Number(amount) > 0, "must be positive"),
|
|
960
959
|
cryptoCurrencyCode: $nonBlank,
|
|
@@ -965,7 +964,16 @@ var $routingQuoteRequest = obj({
|
|
|
965
964
|
{ message: US_REGION_REQUIRED, path: ["region"] }
|
|
966
965
|
),
|
|
967
966
|
prepareSessionAuth: z.boolean().optional()
|
|
968
|
-
}
|
|
967
|
+
};
|
|
968
|
+
var $routingQuoteTerms = obj($routingQuoteTermsShape);
|
|
969
|
+
var FiatRoutingQuoteTermsSchema = $routingQuoteTerms;
|
|
970
|
+
var $routingQuoteRequest = z.union([
|
|
971
|
+
obj({
|
|
972
|
+
...$routingQuoteTermsShape,
|
|
973
|
+
providers: z.array($routingProvider).min(1).refine((providers) => hasUniqueIds(providers), "each provider is listed once")
|
|
974
|
+
}),
|
|
975
|
+
obj({ ...$routingQuoteTermsShape, provider: $routingProvider })
|
|
976
|
+
]);
|
|
969
977
|
var FiatRoutingQuoteRequestSchema = $routingQuoteRequest;
|
|
970
978
|
var $routingServiceableRange = obj({ min: $money, max: $money, userMax: $money.nullable().optional() });
|
|
971
979
|
var $noRouteFields = {
|
|
@@ -2287,6 +2295,7 @@ export {
|
|
|
2287
2295
|
FiatProviderSchema,
|
|
2288
2296
|
FiatRoutingQuoteErrorBodySchema,
|
|
2289
2297
|
FiatRoutingQuoteRequestSchema,
|
|
2298
|
+
FiatRoutingQuoteTermsSchema,
|
|
2290
2299
|
FiatRoutingTableErrorBodySchema,
|
|
2291
2300
|
FiatRoutingTableQuerySchema,
|
|
2292
2301
|
FiatRoutingTableResponseSchema,
|
package/dist/routing.d.ts
CHANGED
|
@@ -82,13 +82,8 @@ export interface FiatRoutingTableResponse {
|
|
|
82
82
|
/** In request order, duplicates removed. */
|
|
83
83
|
methods: RoutingTableMethod[];
|
|
84
84
|
}
|
|
85
|
-
/**
|
|
86
|
-
|
|
87
|
-
* provider, and never `routingOverrides`. The response is the same `FiatStepResponse` as
|
|
88
|
-
* `POST /fiat/quote`; a refusal is a `FiatRoutingQuoteErrorBody`.
|
|
89
|
-
*/
|
|
90
|
-
export interface FiatRoutingQuoteRequest {
|
|
91
|
-
provider: RoutingProvider;
|
|
85
|
+
/** The `POST /fiat/quote` body without `routingOverrides`: everything but which providers to price. */
|
|
86
|
+
export interface FiatRoutingQuoteTerms {
|
|
92
87
|
fiatCurrency: FiatCurrencyCode;
|
|
93
88
|
/** A positive decimal string with no leading zero, exponent or sign (`"20"`, `"20.5"`). */
|
|
94
89
|
fiatAmount: string;
|
|
@@ -107,6 +102,25 @@ export interface FiatRoutingQuoteRequest {
|
|
|
107
102
|
};
|
|
108
103
|
prepareSessionAuth?: boolean;
|
|
109
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* `POST /fiat/routing/quote`: the terms plus which providers to price, in one of two forms.
|
|
107
|
+
*
|
|
108
|
+
* - `providers`: the interval's providers, best first. The backend prices the first, and falls
|
|
109
|
+
* through to the next on a refusal that is that provider's alone (a `FiatNoRouteError` of any
|
|
110
|
+
* `reason`, or either amount error), as the client did before. It answers the first provider that
|
|
111
|
+
* prices, or the last provider's refusal. Any other refusal stops at once.
|
|
112
|
+
* - `provider`: one provider only, with no fall-through. Kept for clients that fall through themselves.
|
|
113
|
+
*
|
|
114
|
+
* The response is the same `FiatStepResponse` as `POST /fiat/quote`, and its `provider` names the
|
|
115
|
+
* one that priced. A refusal is a `FiatRoutingQuoteErrorBody`.
|
|
116
|
+
*/
|
|
117
|
+
export type FiatRoutingQuoteRequest = FiatRoutingQuoteTerms & ({
|
|
118
|
+
providers: RoutingProvider[];
|
|
119
|
+
provider?: never;
|
|
120
|
+
} | {
|
|
121
|
+
provider: RoutingProvider;
|
|
122
|
+
providers?: never;
|
|
123
|
+
});
|
|
110
124
|
/** One serviceable range of the named provider. `userMax` is this buyer's own ceiling inside it, `null` when unmeasured. */
|
|
111
125
|
export interface RoutingServiceableRange {
|
|
112
126
|
min: FiatAmount;
|
|
@@ -160,8 +174,9 @@ export type RoutingFaultErrorBody = ErrorBodyFields & {
|
|
|
160
174
|
export type FiatRoutingTableErrorBody = RoutingRateLimitedErrorBody | RoutingFaultErrorBody;
|
|
161
175
|
/**
|
|
162
176
|
* `POST /fiat/routing/quote` refusals. A `FiatNoRouteError` (any `reason`) or either amount error is
|
|
163
|
-
* the named provider's alone
|
|
164
|
-
*
|
|
177
|
+
* the named provider's alone, so the next provider may still price: with `providers` the backend
|
|
178
|
+
* tries it, with `provider` the client does. Anything else stops the fall-through: a validation or
|
|
179
|
+
* auth refusal, a 5xx, or no provider left to try.
|
|
165
180
|
*/
|
|
166
181
|
export type FiatRoutingQuoteErrorBody = RoutingNoRouteErrorBody | RoutingAmountErrorBody | RoutingFaultErrorBody;
|
|
167
182
|
export {};
|
package/dist/routing.mjs
CHANGED
package/dist/schemas.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ import { z } from 'zod';
|
|
|
30
30
|
import type { UsStateCode } from './codes';
|
|
31
31
|
import type { BlockedReason, CryptoAmount, FailureReason, FeeLine, FiatAmount, FiatEndpoint, FiatProvider, FiatStepResponse, FieldSpec, FlowState, FormDescriptor, FormField, FormFieldType, InstructionField, Instructions, Instrument, JsonValue, KYCProvider, OrderRef, OrderStatus, OrderSummary, PollSpec, PreparedPayment, PaymentSurface, Quote, QuoteLimitRange, QuoteLimits, Recovery, Refund, ReportSpec, SelectOption, StatusHistoryEntry, Surface, PreferredIdentityDocument, KycFieldId, ClientExecutedDelivery, KycSdkResultReport, SurfaceKind, SurfaceProvider, TermsAcceptance, Transition, TransitionInputs, TransitionParams, Tx, FiatGeo, FiatNextRequest } from './types';
|
|
32
32
|
import type { FiatTermsErrorBody, FiatTermsRequest, FiatTermsResponse, TermsDocument, TermsDocumentAcceptance } from './terms';
|
|
33
|
-
import type { FiatRoutingQuoteErrorBody, FiatRoutingQuoteRequest, FiatRoutingTableErrorBody, FiatRoutingTableQuery, FiatRoutingTableResponse } from './routing';
|
|
33
|
+
import type { FiatRoutingQuoteErrorBody, FiatRoutingQuoteRequest, FiatRoutingQuoteTerms, FiatRoutingTableErrorBody, FiatRoutingTableQuery, FiatRoutingTableResponse } from './routing';
|
|
34
34
|
export declare const JsonSchema: z.ZodType<JsonValue>;
|
|
35
35
|
export declare const HTTP_VERBS: readonly ["GET", "POST"];
|
|
36
36
|
/** `"POST /fiat/session/verify"`, `"GET /fiat/orders/o_31c"` — the verb rides the string. */
|
|
@@ -114,6 +114,7 @@ export declare const FiatTermsResponseSchema: z.ZodType<FiatTermsResponse>;
|
|
|
114
114
|
export declare const FiatTermsErrorBodySchema: z.ZodType<FiatTermsErrorBody>;
|
|
115
115
|
export declare const FiatRoutingTableQuerySchema: z.ZodType<FiatRoutingTableQuery>;
|
|
116
116
|
export declare const FiatRoutingTableResponseSchema: z.ZodType<FiatRoutingTableResponse>;
|
|
117
|
+
export declare const FiatRoutingQuoteTermsSchema: z.ZodType<FiatRoutingQuoteTerms>;
|
|
117
118
|
export declare const FiatRoutingQuoteRequestSchema: z.ZodType<FiatRoutingQuoteRequest>;
|
|
118
119
|
export declare const FiatRoutingTableErrorBodySchema: z.ZodType<FiatRoutingTableErrorBody>;
|
|
119
120
|
export declare const FiatRoutingQuoteErrorBodySchema: z.ZodType<FiatRoutingQuoteErrorBody>;
|
package/dist/table.js
CHANGED
package/dist/table.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fun-xyz/fiat-contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Published conformance contract for Fun's headless fiat onramp: FlowState/Transition types, zod schemas, the transition table as data, recorded fixtures, assertion helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|