@fun-xyz/fiat-contract 0.20.2 → 0.22.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 +27 -17
- package/dist/chunk-5GRPYE2U.mjs +44 -0
- package/dist/{chunk-CYT2NARF.mjs → chunk-7OUDI3JX.mjs} +2 -2
- package/dist/{chunk-WW26WEZO.mjs → chunk-SJ7V3YOM.mjs} +1 -1
- package/dist/index.js +43 -17
- package/dist/index.mjs +15 -20
- package/dist/providers/moonpay.d.ts +21 -11
- package/dist/providers/moonpay.mjs +1 -1
- package/dist/table.js +1 -1
- package/dist/table.mjs +1 -1
- package/dist/terms.d.ts +20 -12
- package/dist/terms.js +38 -1
- package/dist/terms.mjs +9 -3
- package/dist/types.d.ts +0 -6
- package/package.json +1 -1
- package/dist/chunk-WRRCWAY2.mjs +0 -7
package/README.md
CHANGED
|
@@ -99,29 +99,35 @@ this package is [ENG-5268](https://linear.app/funxyz/issue/ENG-5268).
|
|
|
99
99
|
|
|
100
100
|
A provider can run its own flow instead of the shared step machine. `POST /fiat/quote` still routes
|
|
101
101
|
and prices. When the request's `handoffs` lists the winning provider, the response carries
|
|
102
|
-
`handoff: { provider
|
|
103
|
-
`POST /fiat/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
offers transitions, and a `terms` entry that is not a unique `CHECKOUT` document.
|
|
102
|
+
`handoff: { provider }` and no transitions. The client shows that provider's `CHECKOUT` documents
|
|
103
|
+
from `PROVIDER_CHECKOUT_DOCUMENTS`, records them with `POST /fiat/terms` on Continue, and then calls
|
|
104
|
+
`POST /fiat/providers/{provider}/intent`. The schema refuses a handoff on any state but `QUOTE`, a
|
|
105
|
+
handoff to a provider other than the response's own, and a handoff that still offers transitions.
|
|
107
106
|
|
|
108
107
|
**Terms (`./terms`).** Every provider records acceptances through the platform `POST /fiat/terms`
|
|
109
|
-
(`FIAT_TERMS_ENDPOINT`)
|
|
110
|
-
(`
|
|
108
|
+
(`FIAT_TERMS_ENDPOINT`). A `TermsDocument` has an `id`, a `kind`
|
|
109
|
+
(`PROVIDER_TERMS`, `FUN_KYC_COLLECTION`, `PROVIDER_KYC_SHARING`), a `stage` (`CHECKOUT` or
|
|
111
110
|
`KYC`), an opaque `version` and `contentDigest`, and at least one `https` link. `FiatTermsRequest` is
|
|
112
111
|
`{ provider, acceptances: [{ documentId, version, contentDigest, acceptedAt }] }`, each document at
|
|
113
112
|
most once; `FiatTermsResponse` is `{ recorded }`, the recorded document ids. A fault is a
|
|
114
113
|
`FiatTermsErrorBody`: the shared `errorCode`, `errorMsg` and `reqId`, plus `reason` (`STALE_TERMS`,
|
|
115
|
-
`
|
|
114
|
+
`INVALID_REQUEST`, `RATE_LIMITED`, `PROVIDER_UNAVAILABLE`) and `recovery`.
|
|
115
|
+
|
|
116
|
+
The package publishes every document as a constant, so the client and the backend read the same
|
|
117
|
+
text. `PROVIDER_CHECKOUT_DOCUMENTS` maps each provider to its current `CHECKOUT` documents.
|
|
118
|
+
`FUN_KYC_CONSENT_DOCUMENTS` is Fun's KYC consent, one digest per `FunKycConsentLocale`.
|
|
119
|
+
`PUBLISHED_TERMS_DOCUMENTS` is every version and locale ever published. Every published version
|
|
120
|
+
stays valid: the backend refuses only an unknown version, a wrong digest, or an `acceptedAt` older
|
|
121
|
+
than 5 minutes. A repeat of a version the login already holds writes nothing and returns the ids.
|
|
116
122
|
|
|
117
123
|
**MoonPay (`./moonpay`).** One route, `MOONPAY_ENDPOINTS.intent`. A `MoonPayIntentRequest` is one of
|
|
118
124
|
three kinds:
|
|
119
125
|
|
|
120
|
-
| `kind` | Carries |
|
|
126
|
+
| `kind` | Carries | A repeat |
|
|
121
127
|
| --- | --- | --- |
|
|
122
|
-
| `observe` | `checkout`, and `credentials` (`customerId`, `accessToken`) once the SDK has them |
|
|
123
|
-
| `kyc` | `checkout`, `credentials`, `values` keyed by `KycFieldId` (no form id) |
|
|
124
|
-
| `order` | `orderId`, `transactionId` |
|
|
128
|
+
| `observe` | `checkout`, and `credentials` (`customerId`, `accessToken`) once the SDK has them | writes nothing new |
|
|
129
|
+
| `kyc` | `checkout`, `credentials`, `values` keyed by `KycFieldId` (no form id) | drops values MoonPay no longer asks for |
|
|
130
|
+
| `order` | `orderId`, `transactionId?`, `quotedAmount` | returns the recorded order |
|
|
125
131
|
|
|
126
132
|
`observe` and `kyc` answer a `MoonPayStepResponse`, which says what the backend needs next:
|
|
127
133
|
|
|
@@ -134,20 +140,24 @@ three kinds:
|
|
|
134
140
|
| `READY` | `orderId`, `quoteInput` | mounts Apple Pay, then sends `order` after the charge |
|
|
135
141
|
| `REFUSED` | `reason` (`NOT_ELIGIBLE`, `DOCUMENTS_REQUIRED`, `FINAL_REJECTION`, `CUSTOMER_MISMATCH`), `recovery: REQUOTE \| NONE` | exits the provider flow |
|
|
136
142
|
|
|
137
|
-
`order` runs after
|
|
143
|
+
`order` runs after every charge attempt, a failed one too, and answers a `MoonPayOrderResponse`.
|
|
144
|
+
`transactionId` is optional because a failed charge may have none; without it the backend records the
|
|
145
|
+
failed charges MoonPay lists for `orderId`. `quotedAmount` is the fiat amount the quote showed. A
|
|
146
|
+
failed charge answers `DONE` with the order in `FAILED`, and the client requotes for a new `orderId`.
|
|
147
|
+
After a failed charge with no `transactionId`, the client caps its `PENDING` polls.
|
|
138
148
|
|
|
139
149
|
| `status` | Carries | The client then |
|
|
140
150
|
| --- | --- | --- |
|
|
141
151
|
| `DONE` | `order`, the `GET /fiat/orders/:orderId` response | shows the shared order status |
|
|
142
|
-
| `PENDING` | `retryAfterMs` (at most 60 s) | sends the same `order
|
|
152
|
+
| `PENDING` | `retryAfterMs` (at most 60 s) | sends the same `order` after the delay |
|
|
143
153
|
| `REFUSED` | `reason` (`CUSTOMER_MISMATCH`, `WALLET_MISMATCH`, `UNRECORDABLE`), `recovery: NONE` | exits the provider flow |
|
|
144
154
|
|
|
145
155
|
`MoonPayIntentResponseFor` maps each `kind` to its union, and `MoonPayIntentResponse` is both.
|
|
146
156
|
|
|
147
157
|
A fault is a 4xx or 5xx with a `MoonPayErrorBody`: the shared `errorCode`, `errorMsg` and `reqId`,
|
|
148
|
-
plus `reason` (`SESSION_BUDGET_SPENT`, `RATE_LIMITED`, `PROVIDER_UNAVAILABLE`, `
|
|
149
|
-
|
|
150
|
-
`RETRY` (send the same request
|
|
158
|
+
plus `reason` (`SESSION_BUDGET_SPENT`, `RATE_LIMITED`, `PROVIDER_UNAVAILABLE`, `INVALID_REQUEST`)
|
|
159
|
+
and `recovery`:
|
|
160
|
+
`RETRY` (send the same request again), `REQUOTE`, or `NONE`. A field error is a `KYC`
|
|
151
161
|
response, not a fault. The zod schemas (`MoonPay*Schema`, `TermsDocumentSchema`, `FiatTerms*Schema`)
|
|
152
162
|
are exported from the root only.
|
|
153
163
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// src/terms.ts
|
|
2
|
+
var FIAT_TERMS_ENDPOINT = "POST /fiat/terms";
|
|
3
|
+
var MOONPAY_TERMS = {
|
|
4
|
+
id: "MOONPAY_TERMS",
|
|
5
|
+
kind: "PROVIDER_TERMS",
|
|
6
|
+
stage: "CHECKOUT",
|
|
7
|
+
version: "2026-09-l2-kyc-sharing-v2",
|
|
8
|
+
contentDigest: "44e096af329262134fe6680659c9bd42014cbf5e96f064d67869173a4f7d822b",
|
|
9
|
+
links: [
|
|
10
|
+
{ label: "MoonPay Terms of Use", url: "https://www.moonpay.com/legal/terms" },
|
|
11
|
+
{ label: "MoonPay Privacy Policy", url: "https://www.moonpay.com/legal/privacy_policy" },
|
|
12
|
+
{ label: "Persona Privacy Policy", url: "https://withpersona.com/legal/privacy-policy" }
|
|
13
|
+
]
|
|
14
|
+
};
|
|
15
|
+
var PROVIDER_CHECKOUT_DOCUMENTS = {
|
|
16
|
+
MOONPAY: [MOONPAY_TERMS]
|
|
17
|
+
};
|
|
18
|
+
var funKycConsent = (contentDigest) => ({
|
|
19
|
+
id: "FUN_KYC_CONSENT",
|
|
20
|
+
kind: "FUN_KYC_COLLECTION",
|
|
21
|
+
stage: "KYC",
|
|
22
|
+
version: "fun-kyc-consent-2026-09-11",
|
|
23
|
+
contentDigest,
|
|
24
|
+
links: [{ label: "Fun.xyz Privacy Policy", url: "https://fun.xyz/privacy" }]
|
|
25
|
+
});
|
|
26
|
+
var FUN_KYC_CONSENT_DOCUMENTS = {
|
|
27
|
+
en: funKycConsent("da31f2467deb996476b131116508ea2a00220765e658a79abc6d2bd44337504a"),
|
|
28
|
+
es: funKycConsent("73753b70ad8d1b48dfdcda35e6028c3a7ada66c311a67a1d8f6fe13c76a32f3b"),
|
|
29
|
+
fr: funKycConsent("5ee82675984591dbf66337f31246179103c5624a189850943d400f9b85a84965"),
|
|
30
|
+
ja: funKycConsent("3f272da313f66601a20c3ca43c967aff4bb7f73488177f0a4ce94cbc78bafce2"),
|
|
31
|
+
ko: funKycConsent("aab7839bfba3f34aa47ca6b10647c2c8965c37d845494ef8f3067ca3e3821200"),
|
|
32
|
+
ru: funKycConsent("17168083ebcc4fd11ea80b08c3f230bdec03a1e7b89173a38819ae5533b0fc96"),
|
|
33
|
+
tr: funKycConsent("463040c3b58c922ecae2ae8262a78eb732bbcc5606c394723626378b3db2bbc3"),
|
|
34
|
+
zh: funKycConsent("7f76d850adaf69783c5d9365e51abb5446f4e5778c63eabbdb4784d72464f855")
|
|
35
|
+
};
|
|
36
|
+
var PUBLISHED_TERMS_DOCUMENTS = [MOONPAY_TERMS, ...Object.values(FUN_KYC_CONSENT_DOCUMENTS)];
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
FIAT_TERMS_ENDPOINT,
|
|
40
|
+
PROVIDER_CHECKOUT_DOCUMENTS,
|
|
41
|
+
FUN_KYC_CONSENT_DOCUMENTS,
|
|
42
|
+
PUBLISHED_TERMS_DOCUMENTS
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=chunk-5GRPYE2U.mjs.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.
|
|
2
|
+
var version = "0.22.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-7OUDI3JX.mjs.map
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
FIELD_SPEC_TYPES: () => FIELD_SPEC_TYPES,
|
|
37
37
|
FIXTURES: () => FIXTURES,
|
|
38
38
|
FIXTURE_COVERAGE_GAPS: () => FIXTURE_COVERAGE_GAPS,
|
|
39
|
+
FUN_KYC_CONSENT_DOCUMENTS: () => FUN_KYC_CONSENT_DOCUMENTS,
|
|
39
40
|
FailureReasonSchema: () => FailureReasonSchema,
|
|
40
41
|
FeeLineSchema: () => FeeLineSchema,
|
|
41
42
|
FiatAmountSchema: () => FiatAmountSchema,
|
|
@@ -80,6 +81,8 @@ __export(index_exports, {
|
|
|
80
81
|
OrderStatusSchema: () => OrderStatusSchema,
|
|
81
82
|
OrderSummarySchema: () => OrderSummarySchema,
|
|
82
83
|
PAYMENT_METHOD_CATEGORIES: () => PAYMENT_METHOD_CATEGORIES,
|
|
84
|
+
PROVIDER_CHECKOUT_DOCUMENTS: () => PROVIDER_CHECKOUT_DOCUMENTS,
|
|
85
|
+
PUBLISHED_TERMS_DOCUMENTS: () => PUBLISHED_TERMS_DOCUMENTS,
|
|
83
86
|
PaymentCaptureStateSchema: () => PaymentCaptureStateSchema,
|
|
84
87
|
PaymentInstructStateSchema: () => PaymentInstructStateSchema,
|
|
85
88
|
PaymentSurfaceSchema: () => PaymentSurfaceSchema,
|
|
@@ -975,7 +978,7 @@ var $nonBlank = import_zod.z.string().refine((value) => value.trim().length > 0,
|
|
|
975
978
|
var $termsStage = import_zod.z.enum(["CHECKOUT", "KYC"]);
|
|
976
979
|
var $termsDocument = obj({
|
|
977
980
|
id: $nonBlank,
|
|
978
|
-
kind: import_zod.z.enum(["
|
|
981
|
+
kind: import_zod.z.enum(["PROVIDER_TERMS", "FUN_KYC_COLLECTION", "PROVIDER_KYC_SHARING"]),
|
|
979
982
|
stage: $termsStage,
|
|
980
983
|
version: $nonBlank,
|
|
981
984
|
contentDigest: $nonBlank,
|
|
@@ -983,10 +986,6 @@ var $termsDocument = obj({
|
|
|
983
986
|
});
|
|
984
987
|
var TermsDocumentSchema = $termsDocument;
|
|
985
988
|
var hasUniqueIds = (ids) => new Set(ids).size === ids.length;
|
|
986
|
-
var $termsDocuments = (stage) => import_zod.z.array($termsDocument).refine((documents) => hasUniqueIds(documents.map((document) => document.id)), "document ids must be unique").refine(
|
|
987
|
-
(documents) => stage === void 0 || documents.every((document) => document.stage === stage),
|
|
988
|
-
`every document must be at stage ${stage}`
|
|
989
|
-
);
|
|
990
989
|
var $termsAcceptance = obj({
|
|
991
990
|
documentId: $nonBlank,
|
|
992
991
|
version: $nonBlank,
|
|
@@ -1005,7 +1004,7 @@ var $termsErrorBody = obj({
|
|
|
1005
1004
|
errorCode: $nonBlank,
|
|
1006
1005
|
errorMsg: import_zod.z.string(),
|
|
1007
1006
|
reqId: import_zod.z.string().optional(),
|
|
1008
|
-
reason: import_zod.z.enum(["STALE_TERMS", "
|
|
1007
|
+
reason: import_zod.z.enum(["STALE_TERMS", "INVALID_REQUEST", "RATE_LIMITED", "PROVIDER_UNAVAILABLE"]),
|
|
1009
1008
|
recovery: import_zod.z.enum(["RETRY", "REQUOTE", "NONE"])
|
|
1010
1009
|
});
|
|
1011
1010
|
var FiatTermsErrorBodySchema = $termsErrorBody;
|
|
@@ -1014,7 +1013,7 @@ var $providerBoundStepResponse = obj({
|
|
|
1014
1013
|
provider: $provider,
|
|
1015
1014
|
transitions: import_zod.z.array($transition),
|
|
1016
1015
|
preparedPayment: $preparedPayment.optional(),
|
|
1017
|
-
handoff: obj({ provider: $provider
|
|
1016
|
+
handoff: obj({ provider: $provider }).optional(),
|
|
1018
1017
|
routingSessionRef: import_zod.z.string().optional(),
|
|
1019
1018
|
providerAuthToken: obj({
|
|
1020
1019
|
clientSecret: import_zod.z.string(),
|
|
@@ -1068,7 +1067,7 @@ var $stepResponse = import_zod.z.union([$providerBoundStepResponse, $blockedStep
|
|
|
1068
1067
|
var FiatStepResponseSchema = $stepResponse;
|
|
1069
1068
|
|
|
1070
1069
|
// package.json
|
|
1071
|
-
var version = "0.
|
|
1070
|
+
var version = "0.22.0";
|
|
1072
1071
|
|
|
1073
1072
|
// src/table.ts
|
|
1074
1073
|
var TABLE_VERSION = version;
|
|
@@ -2636,6 +2635,40 @@ function assertAllFixtures() {
|
|
|
2636
2635
|
|
|
2637
2636
|
// src/terms.ts
|
|
2638
2637
|
var FIAT_TERMS_ENDPOINT = "POST /fiat/terms";
|
|
2638
|
+
var MOONPAY_TERMS = {
|
|
2639
|
+
id: "MOONPAY_TERMS",
|
|
2640
|
+
kind: "PROVIDER_TERMS",
|
|
2641
|
+
stage: "CHECKOUT",
|
|
2642
|
+
version: "2026-09-l2-kyc-sharing-v2",
|
|
2643
|
+
contentDigest: "44e096af329262134fe6680659c9bd42014cbf5e96f064d67869173a4f7d822b",
|
|
2644
|
+
links: [
|
|
2645
|
+
{ label: "MoonPay Terms of Use", url: "https://www.moonpay.com/legal/terms" },
|
|
2646
|
+
{ label: "MoonPay Privacy Policy", url: "https://www.moonpay.com/legal/privacy_policy" },
|
|
2647
|
+
{ label: "Persona Privacy Policy", url: "https://withpersona.com/legal/privacy-policy" }
|
|
2648
|
+
]
|
|
2649
|
+
};
|
|
2650
|
+
var PROVIDER_CHECKOUT_DOCUMENTS = {
|
|
2651
|
+
MOONPAY: [MOONPAY_TERMS]
|
|
2652
|
+
};
|
|
2653
|
+
var funKycConsent = (contentDigest) => ({
|
|
2654
|
+
id: "FUN_KYC_CONSENT",
|
|
2655
|
+
kind: "FUN_KYC_COLLECTION",
|
|
2656
|
+
stage: "KYC",
|
|
2657
|
+
version: "fun-kyc-consent-2026-09-11",
|
|
2658
|
+
contentDigest,
|
|
2659
|
+
links: [{ label: "Fun.xyz Privacy Policy", url: "https://fun.xyz/privacy" }]
|
|
2660
|
+
});
|
|
2661
|
+
var FUN_KYC_CONSENT_DOCUMENTS = {
|
|
2662
|
+
en: funKycConsent("da31f2467deb996476b131116508ea2a00220765e658a79abc6d2bd44337504a"),
|
|
2663
|
+
es: funKycConsent("73753b70ad8d1b48dfdcda35e6028c3a7ada66c311a67a1d8f6fe13c76a32f3b"),
|
|
2664
|
+
fr: funKycConsent("5ee82675984591dbf66337f31246179103c5624a189850943d400f9b85a84965"),
|
|
2665
|
+
ja: funKycConsent("3f272da313f66601a20c3ca43c967aff4bb7f73488177f0a4ce94cbc78bafce2"),
|
|
2666
|
+
ko: funKycConsent("aab7839bfba3f34aa47ca6b10647c2c8965c37d845494ef8f3067ca3e3821200"),
|
|
2667
|
+
ru: funKycConsent("17168083ebcc4fd11ea80b08c3f230bdec03a1e7b89173a38819ae5533b0fc96"),
|
|
2668
|
+
tr: funKycConsent("463040c3b58c922ecae2ae8262a78eb732bbcc5606c394723626378b3db2bbc3"),
|
|
2669
|
+
zh: funKycConsent("7f76d850adaf69783c5d9365e51abb5446f4e5778c63eabbdb4784d72464f855")
|
|
2670
|
+
};
|
|
2671
|
+
var PUBLISHED_TERMS_DOCUMENTS = [MOONPAY_TERMS, ...Object.values(FUN_KYC_CONSENT_DOCUMENTS)];
|
|
2639
2672
|
|
|
2640
2673
|
// src/providers/moonpay.ts
|
|
2641
2674
|
var MOONPAY_ENDPOINTS = {
|
|
@@ -2665,7 +2698,7 @@ var $intentRequest = import_zod2.z.discriminatedUnion("kind", [
|
|
|
2665
2698
|
credentials: $credentials,
|
|
2666
2699
|
values: import_zod2.z.record(KycFieldIdSchema, import_zod2.z.string()).refine((values) => Object.keys(values).length > 0, "values must not be empty")
|
|
2667
2700
|
}),
|
|
2668
|
-
obj2({ kind: import_zod2.z.literal("order"), orderId: $nonEmpty, transactionId: $nonEmpty })
|
|
2701
|
+
obj2({ kind: import_zod2.z.literal("order"), orderId: $nonEmpty, transactionId: $nonEmpty.optional(), quotedAmount: FiatAmountSchema })
|
|
2669
2702
|
]);
|
|
2670
2703
|
var MoonPayIntentRequestSchema = $intentRequest;
|
|
2671
2704
|
var $quoteInput = obj2({
|
|
@@ -2717,14 +2750,7 @@ var MoonPayOrderResponseSchema = $orderResponse;
|
|
|
2717
2750
|
var $intentResponse = import_zod2.z.union([$stepResponse2, $orderResponse]);
|
|
2718
2751
|
var MoonPayIntentResponseSchema = $intentResponse;
|
|
2719
2752
|
var $faultFields = {
|
|
2720
|
-
reason: import_zod2.z.enum([
|
|
2721
|
-
"SESSION_BUDGET_SPENT",
|
|
2722
|
-
"RATE_LIMITED",
|
|
2723
|
-
"PROVIDER_UNAVAILABLE",
|
|
2724
|
-
"IN_PROGRESS",
|
|
2725
|
-
"IDEMPOTENCY_KEY_REUSED",
|
|
2726
|
-
"INVALID_REQUEST"
|
|
2727
|
-
]),
|
|
2753
|
+
reason: import_zod2.z.enum(["SESSION_BUDGET_SPENT", "RATE_LIMITED", "PROVIDER_UNAVAILABLE", "INVALID_REQUEST"]),
|
|
2728
2754
|
recovery: import_zod2.z.enum(["RETRY", "REQUOTE", "NONE"])
|
|
2729
2755
|
};
|
|
2730
2756
|
var $fault = obj2($faultFields);
|
package/dist/index.mjs
CHANGED
|
@@ -12,13 +12,16 @@ import {
|
|
|
12
12
|
tableEntry,
|
|
13
13
|
unofferedEndpoints,
|
|
14
14
|
unreachableStates
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-7OUDI3JX.mjs";
|
|
16
16
|
import {
|
|
17
17
|
MOONPAY_ENDPOINTS
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SJ7V3YOM.mjs";
|
|
19
19
|
import {
|
|
20
|
-
FIAT_TERMS_ENDPOINT
|
|
21
|
-
|
|
20
|
+
FIAT_TERMS_ENDPOINT,
|
|
21
|
+
FUN_KYC_CONSENT_DOCUMENTS,
|
|
22
|
+
PROVIDER_CHECKOUT_DOCUMENTS,
|
|
23
|
+
PUBLISHED_TERMS_DOCUMENTS
|
|
24
|
+
} from "./chunk-5GRPYE2U.mjs";
|
|
22
25
|
|
|
23
26
|
// src/codes.ts
|
|
24
27
|
var US_STATE_CODES = [
|
|
@@ -859,7 +862,7 @@ var $nonBlank = z.string().refine((value) => value.trim().length > 0, "must not
|
|
|
859
862
|
var $termsStage = z.enum(["CHECKOUT", "KYC"]);
|
|
860
863
|
var $termsDocument = obj({
|
|
861
864
|
id: $nonBlank,
|
|
862
|
-
kind: z.enum(["
|
|
865
|
+
kind: z.enum(["PROVIDER_TERMS", "FUN_KYC_COLLECTION", "PROVIDER_KYC_SHARING"]),
|
|
863
866
|
stage: $termsStage,
|
|
864
867
|
version: $nonBlank,
|
|
865
868
|
contentDigest: $nonBlank,
|
|
@@ -867,10 +870,6 @@ var $termsDocument = obj({
|
|
|
867
870
|
});
|
|
868
871
|
var TermsDocumentSchema = $termsDocument;
|
|
869
872
|
var hasUniqueIds = (ids) => new Set(ids).size === ids.length;
|
|
870
|
-
var $termsDocuments = (stage) => z.array($termsDocument).refine((documents) => hasUniqueIds(documents.map((document) => document.id)), "document ids must be unique").refine(
|
|
871
|
-
(documents) => stage === void 0 || documents.every((document) => document.stage === stage),
|
|
872
|
-
`every document must be at stage ${stage}`
|
|
873
|
-
);
|
|
874
873
|
var $termsAcceptance = obj({
|
|
875
874
|
documentId: $nonBlank,
|
|
876
875
|
version: $nonBlank,
|
|
@@ -889,7 +888,7 @@ var $termsErrorBody = obj({
|
|
|
889
888
|
errorCode: $nonBlank,
|
|
890
889
|
errorMsg: z.string(),
|
|
891
890
|
reqId: z.string().optional(),
|
|
892
|
-
reason: z.enum(["STALE_TERMS", "
|
|
891
|
+
reason: z.enum(["STALE_TERMS", "INVALID_REQUEST", "RATE_LIMITED", "PROVIDER_UNAVAILABLE"]),
|
|
893
892
|
recovery: z.enum(["RETRY", "REQUOTE", "NONE"])
|
|
894
893
|
});
|
|
895
894
|
var FiatTermsErrorBodySchema = $termsErrorBody;
|
|
@@ -898,7 +897,7 @@ var $providerBoundStepResponse = obj({
|
|
|
898
897
|
provider: $provider,
|
|
899
898
|
transitions: z.array($transition),
|
|
900
899
|
preparedPayment: $preparedPayment.optional(),
|
|
901
|
-
handoff: obj({ provider: $provider
|
|
900
|
+
handoff: obj({ provider: $provider }).optional(),
|
|
902
901
|
routingSessionRef: z.string().optional(),
|
|
903
902
|
providerAuthToken: obj({
|
|
904
903
|
clientSecret: z.string(),
|
|
@@ -2039,7 +2038,7 @@ var $intentRequest = z2.discriminatedUnion("kind", [
|
|
|
2039
2038
|
credentials: $credentials,
|
|
2040
2039
|
values: z2.record(KycFieldIdSchema, z2.string()).refine((values) => Object.keys(values).length > 0, "values must not be empty")
|
|
2041
2040
|
}),
|
|
2042
|
-
obj2({ kind: z2.literal("order"), orderId: $nonEmpty, transactionId: $nonEmpty })
|
|
2041
|
+
obj2({ kind: z2.literal("order"), orderId: $nonEmpty, transactionId: $nonEmpty.optional(), quotedAmount: FiatAmountSchema })
|
|
2043
2042
|
]);
|
|
2044
2043
|
var MoonPayIntentRequestSchema = $intentRequest;
|
|
2045
2044
|
var $quoteInput = obj2({
|
|
@@ -2091,14 +2090,7 @@ var MoonPayOrderResponseSchema = $orderResponse;
|
|
|
2091
2090
|
var $intentResponse = z2.union([$stepResponse2, $orderResponse]);
|
|
2092
2091
|
var MoonPayIntentResponseSchema = $intentResponse;
|
|
2093
2092
|
var $faultFields = {
|
|
2094
|
-
reason: z2.enum([
|
|
2095
|
-
"SESSION_BUDGET_SPENT",
|
|
2096
|
-
"RATE_LIMITED",
|
|
2097
|
-
"PROVIDER_UNAVAILABLE",
|
|
2098
|
-
"IN_PROGRESS",
|
|
2099
|
-
"IDEMPOTENCY_KEY_REUSED",
|
|
2100
|
-
"INVALID_REQUEST"
|
|
2101
|
-
]),
|
|
2093
|
+
reason: z2.enum(["SESSION_BUDGET_SPENT", "RATE_LIMITED", "PROVIDER_UNAVAILABLE", "INVALID_REQUEST"]),
|
|
2102
2094
|
recovery: z2.enum(["RETRY", "REQUOTE", "NONE"])
|
|
2103
2095
|
};
|
|
2104
2096
|
var $fault = obj2($faultFields);
|
|
@@ -2122,6 +2114,7 @@ export {
|
|
|
2122
2114
|
FIELD_SPEC_TYPES,
|
|
2123
2115
|
FIXTURES,
|
|
2124
2116
|
FIXTURE_COVERAGE_GAPS,
|
|
2117
|
+
FUN_KYC_CONSENT_DOCUMENTS,
|
|
2125
2118
|
FailureReasonSchema,
|
|
2126
2119
|
FeeLineSchema,
|
|
2127
2120
|
FiatAmountSchema,
|
|
@@ -2166,6 +2159,8 @@ export {
|
|
|
2166
2159
|
OrderStatusSchema,
|
|
2167
2160
|
OrderSummarySchema,
|
|
2168
2161
|
PAYMENT_METHOD_CATEGORIES,
|
|
2162
|
+
PROVIDER_CHECKOUT_DOCUMENTS,
|
|
2163
|
+
PUBLISHED_TERMS_DOCUMENTS,
|
|
2169
2164
|
PaymentCaptureStateSchema,
|
|
2170
2165
|
PaymentInstructStateSchema,
|
|
2171
2166
|
PaymentSurfaceSchema,
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* the platform `POST /fiat/terms` (`./terms`). Identity and the deposit wallet always come from the
|
|
8
8
|
* verified partner assertion, never from a request body.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* A retry sends the same request. Each write is idempotent on data the request carries, and every
|
|
11
|
+
* call, a retry too, returns the current response.
|
|
12
12
|
*
|
|
13
13
|
* A fault is a 4xx/5xx whose body is `MoonPayErrorBody`. Anything the user can act on is a 200
|
|
14
14
|
* `MoonPayIntentResponse`.
|
|
@@ -57,11 +57,16 @@ export type MoonPayIntentRequest =
|
|
|
57
57
|
credentials: MoonPaySdkCredentials;
|
|
58
58
|
values: Partial<Record<KycFieldId, string>>;
|
|
59
59
|
}
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* After every charge attempt, a failed one too. `transactionId` is from the Apple Pay event when it
|
|
62
|
+
* has one; without it the backend records the failed charges MoonPay lists for `orderId`.
|
|
63
|
+
* `quotedAmount` is the fiat amount the buyer saw on the quote.
|
|
64
|
+
*/
|
|
61
65
|
| {
|
|
62
66
|
kind: 'order';
|
|
63
67
|
orderId: string;
|
|
64
|
-
transactionId
|
|
68
|
+
transactionId?: string;
|
|
69
|
+
quotedAmount: FiatAmount;
|
|
65
70
|
};
|
|
66
71
|
export type MoonPayIntentKind = MoonPayIntentRequest['kind'];
|
|
67
72
|
/**
|
|
@@ -138,14 +143,20 @@ export type MoonPayStepResponse =
|
|
|
138
143
|
reason: MoonPayStepRefusal;
|
|
139
144
|
recovery: 'REQUOTE' | 'NONE';
|
|
140
145
|
};
|
|
141
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* The answer to `order`, which runs after each charge attempt. A failed charge is recorded too: it
|
|
148
|
+
* answers `DONE` with the order in `FAILED`, and the client requotes for a new `orderId`.
|
|
149
|
+
*/
|
|
142
150
|
export type MoonPayOrderResponse =
|
|
143
151
|
/** The `GET /fiat/orders/:orderId` response; the shared order screen renders it. */
|
|
144
152
|
{
|
|
145
153
|
status: 'DONE';
|
|
146
154
|
order: FiatStepResponse;
|
|
147
155
|
}
|
|
148
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* MoonPay does not list the transaction yet. Send the same `order` after the delay. After a failed
|
|
158
|
+
* charge with no `transactionId`, the client caps these polls.
|
|
159
|
+
*/
|
|
149
160
|
| {
|
|
150
161
|
status: 'PENDING';
|
|
151
162
|
retryAfterMs: number;
|
|
@@ -163,15 +174,14 @@ export type MoonPayIntentResponseFor = {
|
|
|
163
174
|
};
|
|
164
175
|
export type MoonPayIntentResponse = MoonPayStepResponse | MoonPayOrderResponse;
|
|
165
176
|
export type MoonPayIntentStatus = MoonPayIntentResponse['status'];
|
|
166
|
-
/** `RETRY` sends the same request again
|
|
177
|
+
/** `RETRY` sends the same request again. `REQUOTE` goes back to `POST /fiat/quote`. `NONE` ends the flow. */
|
|
167
178
|
export type MoonPayRecovery = 'RETRY' | 'REQUOTE' | 'NONE';
|
|
168
179
|
/**
|
|
169
180
|
* `SESSION_BUDGET_SPENT`: the per-login SDK session mint budget (429). `RATE_LIMITED`: the kind's
|
|
170
|
-
* request budget (429). `PROVIDER_UNAVAILABLE`: MoonPay or Sumsub is down. `
|
|
171
|
-
*
|
|
172
|
-
* `INVALID_REQUEST`: a bad body or a missing key (400).
|
|
181
|
+
* request budget (429). `PROVIDER_UNAVAILABLE`: MoonPay or Sumsub is down. `INVALID_REQUEST`: a bad
|
|
182
|
+
* body (400).
|
|
173
183
|
*/
|
|
174
|
-
export type MoonPayFaultReason = 'SESSION_BUDGET_SPENT' | 'RATE_LIMITED' | 'PROVIDER_UNAVAILABLE' | '
|
|
184
|
+
export type MoonPayFaultReason = 'SESSION_BUDGET_SPENT' | 'RATE_LIMITED' | 'PROVIDER_UNAVAILABLE' | 'INVALID_REQUEST';
|
|
175
185
|
/** The fields a MoonPay fault adds to the shared error body. */
|
|
176
186
|
export interface MoonPayFault {
|
|
177
187
|
reason: MoonPayFaultReason;
|
package/dist/table.js
CHANGED
package/dist/table.mjs
CHANGED
package/dist/terms.d.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The platform terms route: `POST /fiat/terms`, shared by every provider.
|
|
3
3
|
*
|
|
4
|
-
* A checkout shows the user documents to accept. `CHECKOUT` documents
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* provider call.
|
|
4
|
+
* A checkout shows the user documents to accept. `CHECKOUT` documents are the constants below;
|
|
5
|
+
* `KYC` documents arrive in a provider flow's `TERMS` response. The user's Continue tap is the
|
|
6
|
+
* acceptance, and the client records it here before the next provider call. A repeat writes nothing.
|
|
8
7
|
*
|
|
9
8
|
* Zero runtime dependencies, so production React Native code can import it. The zod schemas are
|
|
10
9
|
* exported from the package root.
|
|
11
10
|
*/
|
|
12
11
|
import type { FiatProvider } from './types';
|
|
13
12
|
export declare const FIAT_TERMS_ENDPOINT: "POST /fiat/terms";
|
|
14
|
-
export type TermsDocumentKind = '
|
|
13
|
+
export type TermsDocumentKind = 'PROVIDER_TERMS' | 'FUN_KYC_COLLECTION' | 'PROVIDER_KYC_SHARING';
|
|
15
14
|
/** `CHECKOUT` documents gate the provider session; `KYC` documents gate the first KYC write. */
|
|
16
15
|
export type TermsStage = 'CHECKOUT' | 'KYC';
|
|
17
16
|
export interface TermsDocument {
|
|
@@ -45,14 +44,13 @@ export interface FiatTermsResponse {
|
|
|
45
44
|
recorded: string[];
|
|
46
45
|
}
|
|
47
46
|
/**
|
|
48
|
-
* `STALE_TERMS`:
|
|
49
|
-
*
|
|
50
|
-
* `
|
|
51
|
-
* or a
|
|
52
|
-
* `PROVIDER_UNAVAILABLE`: the KYC service or a store is down (503); nothing is recorded, so retry.
|
|
47
|
+
* `STALE_TERMS`: an unpublished version, a wrong digest, or an `acceptedAt` older than 5 minutes
|
|
48
|
+
* (400). `INVALID_REQUEST`: a bad body (400).
|
|
49
|
+
* `RATE_LIMITED`: the per-login terms budget is spent (429). `PROVIDER_UNAVAILABLE`: the KYC service
|
|
50
|
+
* or a store is down (503); nothing is recorded, so retry.
|
|
53
51
|
*/
|
|
54
|
-
export type FiatTermsFaultReason = 'STALE_TERMS' | '
|
|
55
|
-
/** `RETRY` sends the same request
|
|
52
|
+
export type FiatTermsFaultReason = 'STALE_TERMS' | 'INVALID_REQUEST' | 'RATE_LIMITED' | 'PROVIDER_UNAVAILABLE';
|
|
53
|
+
/** `RETRY` sends the same request again. `REQUOTE` goes back to `POST /fiat/quote`. `NONE` ends the flow. */
|
|
56
54
|
export type FiatTermsRecovery = 'RETRY' | 'REQUOTE' | 'NONE';
|
|
57
55
|
/** The 4xx/5xx body of `POST /fiat/terms`: the shared error body plus `reason` and `recovery`. */
|
|
58
56
|
export interface FiatTermsErrorBody {
|
|
@@ -62,4 +60,14 @@ export interface FiatTermsErrorBody {
|
|
|
62
60
|
reason: FiatTermsFaultReason;
|
|
63
61
|
recovery: FiatTermsRecovery;
|
|
64
62
|
}
|
|
63
|
+
/** Each provider's current `CHECKOUT` documents, shown next to Continue on the amount screen. */
|
|
64
|
+
export declare const PROVIDER_CHECKOUT_DOCUMENTS: Readonly<Partial<Record<FiatProvider, readonly TermsDocument[]>>>;
|
|
65
|
+
export type FunKycConsentLocale = 'en' | 'es' | 'fr' | 'ja' | 'ko' | 'ru' | 'tr' | 'zh';
|
|
66
|
+
/** Fun's KYC consent, one digest per locale the KYC intro screen shows. It counts under any provider. */
|
|
67
|
+
export declare const FUN_KYC_CONSENT_DOCUMENTS: Readonly<Record<FunKycConsentLocale, TermsDocument>>;
|
|
68
|
+
/**
|
|
69
|
+
* Every version and locale ever published. Append a new version here and keep the old one: the
|
|
70
|
+
* backend accepts any entry, so a client that ships an older version can still check out.
|
|
71
|
+
*/
|
|
72
|
+
export declare const PUBLISHED_TERMS_DOCUMENTS: readonly TermsDocument[];
|
|
65
73
|
//# sourceMappingURL=terms.d.ts.map
|
package/dist/terms.js
CHANGED
|
@@ -20,8 +20,45 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/terms.ts
|
|
21
21
|
var terms_exports = {};
|
|
22
22
|
__export(terms_exports, {
|
|
23
|
-
FIAT_TERMS_ENDPOINT: () => FIAT_TERMS_ENDPOINT
|
|
23
|
+
FIAT_TERMS_ENDPOINT: () => FIAT_TERMS_ENDPOINT,
|
|
24
|
+
FUN_KYC_CONSENT_DOCUMENTS: () => FUN_KYC_CONSENT_DOCUMENTS,
|
|
25
|
+
PROVIDER_CHECKOUT_DOCUMENTS: () => PROVIDER_CHECKOUT_DOCUMENTS,
|
|
26
|
+
PUBLISHED_TERMS_DOCUMENTS: () => PUBLISHED_TERMS_DOCUMENTS
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(terms_exports);
|
|
26
29
|
var FIAT_TERMS_ENDPOINT = "POST /fiat/terms";
|
|
30
|
+
var MOONPAY_TERMS = {
|
|
31
|
+
id: "MOONPAY_TERMS",
|
|
32
|
+
kind: "PROVIDER_TERMS",
|
|
33
|
+
stage: "CHECKOUT",
|
|
34
|
+
version: "2026-09-l2-kyc-sharing-v2",
|
|
35
|
+
contentDigest: "44e096af329262134fe6680659c9bd42014cbf5e96f064d67869173a4f7d822b",
|
|
36
|
+
links: [
|
|
37
|
+
{ label: "MoonPay Terms of Use", url: "https://www.moonpay.com/legal/terms" },
|
|
38
|
+
{ label: "MoonPay Privacy Policy", url: "https://www.moonpay.com/legal/privacy_policy" },
|
|
39
|
+
{ label: "Persona Privacy Policy", url: "https://withpersona.com/legal/privacy-policy" }
|
|
40
|
+
]
|
|
41
|
+
};
|
|
42
|
+
var PROVIDER_CHECKOUT_DOCUMENTS = {
|
|
43
|
+
MOONPAY: [MOONPAY_TERMS]
|
|
44
|
+
};
|
|
45
|
+
var funKycConsent = (contentDigest) => ({
|
|
46
|
+
id: "FUN_KYC_CONSENT",
|
|
47
|
+
kind: "FUN_KYC_COLLECTION",
|
|
48
|
+
stage: "KYC",
|
|
49
|
+
version: "fun-kyc-consent-2026-09-11",
|
|
50
|
+
contentDigest,
|
|
51
|
+
links: [{ label: "Fun.xyz Privacy Policy", url: "https://fun.xyz/privacy" }]
|
|
52
|
+
});
|
|
53
|
+
var FUN_KYC_CONSENT_DOCUMENTS = {
|
|
54
|
+
en: funKycConsent("da31f2467deb996476b131116508ea2a00220765e658a79abc6d2bd44337504a"),
|
|
55
|
+
es: funKycConsent("73753b70ad8d1b48dfdcda35e6028c3a7ada66c311a67a1d8f6fe13c76a32f3b"),
|
|
56
|
+
fr: funKycConsent("5ee82675984591dbf66337f31246179103c5624a189850943d400f9b85a84965"),
|
|
57
|
+
ja: funKycConsent("3f272da313f66601a20c3ca43c967aff4bb7f73488177f0a4ce94cbc78bafce2"),
|
|
58
|
+
ko: funKycConsent("aab7839bfba3f34aa47ca6b10647c2c8965c37d845494ef8f3067ca3e3821200"),
|
|
59
|
+
ru: funKycConsent("17168083ebcc4fd11ea80b08c3f230bdec03a1e7b89173a38819ae5533b0fc96"),
|
|
60
|
+
tr: funKycConsent("463040c3b58c922ecae2ae8262a78eb732bbcc5606c394723626378b3db2bbc3"),
|
|
61
|
+
zh: funKycConsent("7f76d850adaf69783c5d9365e51abb5446f4e5778c63eabbdb4784d72464f855")
|
|
62
|
+
};
|
|
63
|
+
var PUBLISHED_TERMS_DOCUMENTS = [MOONPAY_TERMS, ...Object.values(FUN_KYC_CONSENT_DOCUMENTS)];
|
|
27
64
|
//# sourceMappingURL=terms.js.map
|
package/dist/terms.mjs
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
|
-
FIAT_TERMS_ENDPOINT
|
|
3
|
-
|
|
2
|
+
FIAT_TERMS_ENDPOINT,
|
|
3
|
+
FUN_KYC_CONSENT_DOCUMENTS,
|
|
4
|
+
PROVIDER_CHECKOUT_DOCUMENTS,
|
|
5
|
+
PUBLISHED_TERMS_DOCUMENTS
|
|
6
|
+
} from "./chunk-5GRPYE2U.mjs";
|
|
4
7
|
export {
|
|
5
|
-
FIAT_TERMS_ENDPOINT
|
|
8
|
+
FIAT_TERMS_ENDPOINT,
|
|
9
|
+
FUN_KYC_CONSENT_DOCUMENTS,
|
|
10
|
+
PROVIDER_CHECKOUT_DOCUMENTS,
|
|
11
|
+
PUBLISHED_TERMS_DOCUMENTS
|
|
6
12
|
};
|
|
7
13
|
//# sourceMappingURL=terms.mjs.map
|
package/dist/types.d.ts
CHANGED
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
* - terminality comes from the table (`src/table.ts`), never from `transitions.length`
|
|
20
20
|
*/
|
|
21
21
|
import type { FiatCurrencyCode, PaymentMethodCategory } from './codes';
|
|
22
|
-
import type { TermsDocument } from './terms';
|
|
23
22
|
/**
|
|
24
23
|
* JSON value. `params` carry these — opaque literals the client spreads verbatim.
|
|
25
24
|
* Named `JsonValue` rather than `Json` because this package's surface is re-exported wholesale;
|
|
@@ -722,11 +721,6 @@ export type FiatStepResponse = (FiatStepResponseBase & {
|
|
|
722
721
|
*/
|
|
723
722
|
handoff?: {
|
|
724
723
|
provider: FiatProvider;
|
|
725
|
-
/**
|
|
726
|
-
* The `CHECKOUT` documents this login has not accepted at the current version, shown next to
|
|
727
|
-
* Continue and recorded with `POST /fiat/terms` on the tap. Empty for a returning buyer.
|
|
728
|
-
*/
|
|
729
|
-
terms: TermsDocument[];
|
|
730
724
|
};
|
|
731
725
|
});
|
|
732
726
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fun-xyz/fiat-contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.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": {
|