@fun-xyz/fiat-contract 0.17.0 → 0.19.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 +21 -2
- package/dist/{chunk-TXRBC2P2.mjs → chunk-G3GKLFI2.mjs} +2 -2
- package/dist/chunk-YWKS7MMT.mjs +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +106 -1
- package/dist/index.mjs +101 -1
- package/dist/providers/moonpay.d.ts +131 -0
- package/dist/providers/moonpay.js +32 -0
- package/dist/providers/moonpay.mjs +7 -0
- package/dist/providers/moonpay.schemas.d.ts +18 -0
- package/dist/table.js +1 -1
- package/dist/table.mjs +1 -1
- package/dist/types.d.ts +11 -0
- package/moonpay.d.ts +1 -0
- package/moonpay.js +2 -0
- package/package.json +11 -1
package/README.md
CHANGED
|
@@ -13,12 +13,13 @@ Four things, zero runtime logic beyond validation:
|
|
|
13
13
|
| `src/table.ts` | the transition table **as data**: per state, its legal transition set, the states any call from it may return, and `terminal: boolean` |
|
|
14
14
|
| `src/assert.ts` + `src/fixtures/` | `assertFiatStepResponse` · `assertLegalEmission` · `assertLegalReturn` · `walkTable` · fixture loader + 18 recorded step responses (inlined as data — no filesystem, so React Native can bundle it) |
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Four entry points — production vs test-time
|
|
17
17
|
|
|
18
18
|
| Import | Weight | Contains | Used by |
|
|
19
19
|
| --- | --- | --- | --- |
|
|
20
20
|
| `@fun-xyz/fiat-contract/types` | **0.1 KB** (types erase) | every type; no runtime values | production, both repos |
|
|
21
21
|
| `@fun-xyz/fiat-contract/table` | **13.8 KB**, zero deps | `TRANSITION_TABLE`, `stateKey`, `tableEntry`, `isTerminal`, `walkTable`, `TABLE_VERSION`, `TERMINAL_ORDER_STATUSES`, `DOCUMENTED_ENDPOINTS`, `UNOFFERED_ENDPOINTS`, `UNREACHABLE_STATES`, `unofferedEndpoints`, `unreachableStates` | **production frontend** + backend |
|
|
22
|
+
| `@fun-xyz/fiat-contract/moonpay` | zero deps | the MoonPay provider-owned flow: request, response, standing and fault types, and `MOONPAY_ENDPOINTS` | **production frontend** (MoonPay adapter) + backend |
|
|
22
23
|
| `@fun-xyz/fiat-contract` | 47.6 KB, needs zod | the above + 46 zod schemas + assertions + 18 fixtures | tests, and backend dev/test guards |
|
|
23
24
|
|
|
24
25
|
`./table` is not a micro-optimisation. Terminality is table data a **shipped** client must read
|
|
@@ -93,6 +94,24 @@ this package is [ENG-5268](https://linear.app/funxyz/issue/ENG-5268).
|
|
|
93
94
|
is not active yet. A client exposes it only after a later response makes the same `quoteRef`
|
|
94
95
|
executable; the prepared surface provider must match the response provider.
|
|
95
96
|
|
|
97
|
+
## Provider-owned flows
|
|
98
|
+
|
|
99
|
+
A provider can run its own flow instead of the shared step machine. `POST /fiat/quote` still routes
|
|
100
|
+
and prices. When the request's `handoffs` lists the winning provider, the response carries
|
|
101
|
+
`handoff: { provider }` and no transitions, and the client calls that provider's routes under
|
|
102
|
+
`POST /fiat/providers/{provider}/…`. The schema refuses a handoff to a provider other than the
|
|
103
|
+
response's own, and a handoff that still offers transitions. When the provider records terms,
|
|
104
|
+
`handoff.termsAcceptance.version` names the revision; the client echoes it in `start`.
|
|
105
|
+
|
|
106
|
+
MoonPay is the first (`./moonpay`). Its routes are `start`, `intent`, `kyc`, and `complete`, in
|
|
107
|
+
`MOONPAY_ENDPOINTS`. Only `intent` decides: it answers with a `MoonPayStanding` (`READY`, `KYC`,
|
|
108
|
+
`PENDING`, or `REFUSED`). `kyc` answers `{ status: 'ACCEPTED' }`, and the client then calls `intent`.
|
|
109
|
+
`complete` answers with the same step response as `GET /fiat/orders/:orderId`. A fault is a 4xx or
|
|
110
|
+
5xx with a `MoonPayErrorBody`: the shared `errorCode`, `errorMsg` and `reqId`, plus `reason`,
|
|
111
|
+
`recovery`, and `fields` on a rejected KYC value. `recovery` is `RETRY` (send the same request),
|
|
112
|
+
`REFRESH` (call `intent` for a new standing, as after a stale form), `REQUOTE`, or `NONE`. The zod
|
|
113
|
+
schemas (`MoonPay*Schema`) are exported from the root only. A handoff appears only on a `QUOTE`.
|
|
114
|
+
|
|
96
115
|
## KYC SDK hints, results, and client delivery
|
|
97
116
|
|
|
98
117
|
`KYC_SDK` is a dedicated `Surface` union member. Its optional
|
|
@@ -444,7 +463,7 @@ Dual CJS + ESM, same shape as `@funkit/fun-relay`, because the two consumers loa
|
|
|
444
463
|
| `require()` must work | `fun-backend/apps/api-server` compiles `module: commonjs` and runs plain node — no bundler | esbuild emits `dist/index.js` (CJS) + `dist/index.mjs` (ESM); `exports` maps `require`/`import`; no `"type": "module"` |
|
|
445
464
|
| Zero Node builtins | `connect-core` is React Native — Metro cannot resolve `node:fs` | fixtures are inlined as generated TS data (`src/fixtures/data.ts`), so nothing touches the filesystem; `platform: browser`, every bare import external |
|
|
446
465
|
| Subpath imports must resolve without `exports` support | Metro only reads `package.json#exports` from RN 0.79 on, and `@funkit/connect-rn` accepts `react-native: >=0.74` | root compat stubs `table.js` / `types.js` (+ `.d.ts`) that re-export `dist/`. Without them Metro fails with *"Unable to resolve module"* — verified, not theorised. Resolvers that do read `exports` never see the stubs |
|
|
447
|
-
| Production code must not pull zod or fixtures | `connect-core` ships to React Native, where Metro does not tree-shake unused exports by default |
|
|
466
|
+
| Production code must not pull zod or fixtures | `connect-core` ships to React Native, where Metro does not tree-shake unused exports by default | four entry points: `./types` (erased), `./table` (13.8 KB, zero deps), `./moonpay` (zero deps), root (schemas + fixtures, test-time). CI asserts `require('.../table')` and `require('.../moonpay')` never load zod |
|
|
448
467
|
| `.d.ts` must not lock a zod major | Both repos run `skipLibCheck: true`, which turns a broken declaration into a silent `any` | every exported schema is annotated `z.ZodType<T>`, so declarations name only `z.ZodType`; the structural drift checks stay module-private |
|
|
449
468
|
|
|
450
469
|
Declarations come from `tsc --emitDeclarationOnly`; esbuild only emits JS. The fixture `.json` files
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// package.json
|
|
2
|
-
var version = "0.
|
|
2
|
+
var version = "0.19.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-G3GKLFI2.mjs.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// src/providers/moonpay.ts
|
|
2
|
+
var MOONPAY_ENDPOINTS = {
|
|
3
|
+
start: "POST /fiat/providers/moonpay/start",
|
|
4
|
+
intent: "POST /fiat/providers/moonpay/intent",
|
|
5
|
+
kyc: "POST /fiat/providers/moonpay/kyc",
|
|
6
|
+
complete: "POST /fiat/providers/moonpay/complete"
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
MOONPAY_ENDPOINTS
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=chunk-YWKS7MMT.mjs.map
|
package/dist/index.d.ts
CHANGED
|
@@ -10,5 +10,7 @@ export * from './codes';
|
|
|
10
10
|
export * from './schemas';
|
|
11
11
|
export * from './table';
|
|
12
12
|
export * from './assert';
|
|
13
|
+
export * from './providers/moonpay';
|
|
14
|
+
export * from './providers/moonpay.schemas';
|
|
13
15
|
export { FIXTURES, FIXTURE_COVERAGE_GAPS, fixtureMeta, loadFixture, loadFixtures, type FixtureMeta, type FixtureSource, type LoadedFixture, } from './fixtures/index';
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -59,6 +59,18 @@ __export(index_exports, {
|
|
|
59
59
|
KycInputRequiredStateSchema: () => KycInputRequiredStateSchema,
|
|
60
60
|
KycNoActionRequiredStateSchema: () => KycNoActionRequiredStateSchema,
|
|
61
61
|
KycSdkResultReportSchema: () => KycSdkResultReportSchema,
|
|
62
|
+
MOONPAY_ENDPOINTS: () => MOONPAY_ENDPOINTS,
|
|
63
|
+
MoonPayCompleteRequestSchema: () => MoonPayCompleteRequestSchema,
|
|
64
|
+
MoonPayCompleteResponseSchema: () => MoonPayCompleteResponseSchema,
|
|
65
|
+
MoonPayErrorBodySchema: () => MoonPayErrorBodySchema,
|
|
66
|
+
MoonPayFaultSchema: () => MoonPayFaultSchema,
|
|
67
|
+
MoonPayIntentRequestSchema: () => MoonPayIntentRequestSchema,
|
|
68
|
+
MoonPayIntentResponseSchema: () => MoonPayIntentResponseSchema,
|
|
69
|
+
MoonPayKycRequestSchema: () => MoonPayKycRequestSchema,
|
|
70
|
+
MoonPayKycResponseSchema: () => MoonPayKycResponseSchema,
|
|
71
|
+
MoonPayStandingSchema: () => MoonPayStandingSchema,
|
|
72
|
+
MoonPayStartRequestSchema: () => MoonPayStartRequestSchema,
|
|
73
|
+
MoonPayStartResponseSchema: () => MoonPayStartResponseSchema,
|
|
62
74
|
OrderAwaitingConfirmationStateSchema: () => OrderAwaitingConfirmationStateSchema,
|
|
63
75
|
OrderCreatedStateSchema: () => OrderCreatedStateSchema,
|
|
64
76
|
OrderRefSchema: () => OrderRefSchema,
|
|
@@ -958,6 +970,7 @@ var $providerBoundStepResponse = obj({
|
|
|
958
970
|
provider: $provider,
|
|
959
971
|
transitions: import_zod.z.array($transition),
|
|
960
972
|
preparedPayment: $preparedPayment.optional(),
|
|
973
|
+
handoff: obj({ provider: $provider, termsAcceptance: obj({ version: import_zod.z.string().min(1) }).optional() }).optional(),
|
|
961
974
|
routingSessionRef: import_zod.z.string().optional(),
|
|
962
975
|
providerAuthToken: obj({
|
|
963
976
|
clientSecret: import_zod.z.string(),
|
|
@@ -973,6 +986,27 @@ var $providerBoundStepResponse = obj({
|
|
|
973
986
|
message: "preparedPayment.surface.provider must match the response provider"
|
|
974
987
|
});
|
|
975
988
|
}
|
|
989
|
+
if (response.handoff !== void 0 && response.handoff.provider !== response.provider) {
|
|
990
|
+
context.addIssue({
|
|
991
|
+
code: "custom",
|
|
992
|
+
path: ["handoff", "provider"],
|
|
993
|
+
message: "handoff.provider must match the response provider"
|
|
994
|
+
});
|
|
995
|
+
}
|
|
996
|
+
if (response.handoff !== void 0 && response.state.kind !== "QUOTE") {
|
|
997
|
+
context.addIssue({
|
|
998
|
+
code: "custom",
|
|
999
|
+
path: ["handoff"],
|
|
1000
|
+
message: "only a QUOTE response hands off to a provider"
|
|
1001
|
+
});
|
|
1002
|
+
}
|
|
1003
|
+
if (response.handoff !== void 0 && response.transitions.length > 0) {
|
|
1004
|
+
context.addIssue({
|
|
1005
|
+
code: "custom",
|
|
1006
|
+
path: ["transitions"],
|
|
1007
|
+
message: "a handoff response carries no transitions"
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
976
1010
|
});
|
|
977
1011
|
var $blockedStepResponse = obj({
|
|
978
1012
|
state: $blockedState,
|
|
@@ -990,7 +1024,7 @@ var $stepResponse = import_zod.z.union([$providerBoundStepResponse, $blockedStep
|
|
|
990
1024
|
var FiatStepResponseSchema = $stepResponse;
|
|
991
1025
|
|
|
992
1026
|
// package.json
|
|
993
|
-
var version = "0.
|
|
1027
|
+
var version = "0.19.0";
|
|
994
1028
|
|
|
995
1029
|
// src/table.ts
|
|
996
1030
|
var TABLE_VERSION = version;
|
|
@@ -2555,4 +2589,75 @@ function assertFixture(id) {
|
|
|
2555
2589
|
function assertAllFixtures() {
|
|
2556
2590
|
return FIXTURES.map((meta) => assertFixture(meta.id));
|
|
2557
2591
|
}
|
|
2592
|
+
|
|
2593
|
+
// src/providers/moonpay.ts
|
|
2594
|
+
var MOONPAY_ENDPOINTS = {
|
|
2595
|
+
start: "POST /fiat/providers/moonpay/start",
|
|
2596
|
+
intent: "POST /fiat/providers/moonpay/intent",
|
|
2597
|
+
kyc: "POST /fiat/providers/moonpay/kyc",
|
|
2598
|
+
complete: "POST /fiat/providers/moonpay/complete"
|
|
2599
|
+
};
|
|
2600
|
+
|
|
2601
|
+
// src/providers/moonpay.schemas.ts
|
|
2602
|
+
var import_zod2 = require("zod");
|
|
2603
|
+
var FIAT_CURRENCY_CODES2 = Object.keys(FIAT_CURRENCY_NAMES);
|
|
2604
|
+
var obj2 = (shape) => import_zod2.z.object(shape).strict();
|
|
2605
|
+
var $nonEmpty = import_zod2.z.string().refine((value) => value.trim().length > 0, "must not be blank");
|
|
2606
|
+
var $startRequest = obj2({
|
|
2607
|
+
amount: FiatAmountSchema,
|
|
2608
|
+
destination: obj2({ asset: $nonEmpty, network: $nonEmpty }),
|
|
2609
|
+
paymentMethod: import_zod2.z.literal("apple_pay"),
|
|
2610
|
+
geo: obj2({ alpha2: import_zod2.z.string().regex(/^[A-Z]{2}$/), region: $nonEmpty.optional(), ip: $nonEmpty.optional() }),
|
|
2611
|
+
termsAcceptance: obj2({ version: $nonEmpty, acceptedAt: import_zod2.z.string().datetime({ offset: true }) })
|
|
2612
|
+
});
|
|
2613
|
+
var MoonPayStartRequestSchema = $startRequest;
|
|
2614
|
+
var $quoteInput = obj2({
|
|
2615
|
+
source: obj2({ asset: obj2({ code: import_zod2.z.enum(FIAT_CURRENCY_CODES2) }), amount: $nonEmpty }),
|
|
2616
|
+
destination: obj2({ asset: obj2({ code: $nonEmpty }) }),
|
|
2617
|
+
wallet: obj2({ address: $nonEmpty }),
|
|
2618
|
+
paymentMethod: obj2({ type: import_zod2.z.literal("apple_pay") }),
|
|
2619
|
+
feeBehavior: import_zod2.z.literal("inclusive")
|
|
2620
|
+
});
|
|
2621
|
+
var $startResponse = obj2({ sessionToken: $nonEmpty, quoteInput: $quoteInput });
|
|
2622
|
+
var MoonPayStartResponseSchema = $startResponse;
|
|
2623
|
+
var $intentRequest = obj2({ customerId: $nonEmpty, accessToken: $nonEmpty });
|
|
2624
|
+
var MoonPayIntentRequestSchema = $intentRequest;
|
|
2625
|
+
var $refusal = import_zod2.z.enum(["DOCUMENTS_REQUIRED", "FINAL_REJECTION", "CUSTOMER_MISMATCH"]);
|
|
2626
|
+
var $standing = import_zod2.z.discriminatedUnion("status", [
|
|
2627
|
+
obj2({ status: import_zod2.z.literal("READY"), orderId: $nonEmpty }),
|
|
2628
|
+
obj2({ status: import_zod2.z.literal("KYC"), form: FormDescriptorSchema }),
|
|
2629
|
+
obj2({ status: import_zod2.z.literal("PENDING"), retryAfterMs: import_zod2.z.number().int().positive().max(6e4) }),
|
|
2630
|
+
obj2({ status: import_zod2.z.literal("REFUSED"), reason: $refusal, recovery: import_zod2.z.enum(["REQUOTE", "NONE"]) })
|
|
2631
|
+
]);
|
|
2632
|
+
var MoonPayStandingSchema = $standing;
|
|
2633
|
+
var MoonPayIntentResponseSchema = $standing;
|
|
2634
|
+
var $kycRequest = obj2({ formId: $nonEmpty, values: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.string()) });
|
|
2635
|
+
var MoonPayKycRequestSchema = $kycRequest;
|
|
2636
|
+
var $kycResponse = obj2({ status: import_zod2.z.literal("ACCEPTED") });
|
|
2637
|
+
var MoonPayKycResponseSchema = $kycResponse;
|
|
2638
|
+
var $completeRequest = obj2({ orderId: $nonEmpty, transactionId: $nonEmpty });
|
|
2639
|
+
var MoonPayCompleteRequestSchema = $completeRequest;
|
|
2640
|
+
var MoonPayCompleteResponseSchema = FiatStepResponseSchema;
|
|
2641
|
+
var $fieldError = obj2({ fieldId: $nonEmpty, message: $nonEmpty });
|
|
2642
|
+
var $faultFields = {
|
|
2643
|
+
reason: import_zod2.z.enum([
|
|
2644
|
+
"NOT_ELIGIBLE",
|
|
2645
|
+
"SESSION_BUDGET_SPENT",
|
|
2646
|
+
"PROVIDER_UNAVAILABLE",
|
|
2647
|
+
"INVALID_VALUE",
|
|
2648
|
+
"STALE_FORM",
|
|
2649
|
+
"TRANSACTION_NOT_VISIBLE",
|
|
2650
|
+
"WALLET_MISMATCH"
|
|
2651
|
+
]),
|
|
2652
|
+
recovery: import_zod2.z.enum(["RETRY", "REFRESH", "REQUOTE", "NONE"]),
|
|
2653
|
+
fields: import_zod2.z.array($fieldError).min(1).optional()
|
|
2654
|
+
};
|
|
2655
|
+
var fieldsOnlyOnInvalidValue = (fault) => fault.reason === "INVALID_VALUE" === (fault.fields !== void 0);
|
|
2656
|
+
var $fault = obj2($faultFields).refine(fieldsOnlyOnInvalidValue, "fields is present exactly when reason is INVALID_VALUE");
|
|
2657
|
+
var MoonPayFaultSchema = $fault;
|
|
2658
|
+
var $errorBody = obj2({ ...$faultFields, errorCode: $nonEmpty, errorMsg: import_zod2.z.string(), reqId: import_zod2.z.string().optional() }).refine(
|
|
2659
|
+
fieldsOnlyOnInvalidValue,
|
|
2660
|
+
"fields is present exactly when reason is INVALID_VALUE"
|
|
2661
|
+
);
|
|
2662
|
+
var MoonPayErrorBodySchema = $errorBody;
|
|
2558
2663
|
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
tableEntry,
|
|
13
13
|
unofferedEndpoints,
|
|
14
14
|
unreachableStates
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-G3GKLFI2.mjs";
|
|
16
|
+
import {
|
|
17
|
+
MOONPAY_ENDPOINTS
|
|
18
|
+
} from "./chunk-YWKS7MMT.mjs";
|
|
16
19
|
|
|
17
20
|
// src/codes.ts
|
|
18
21
|
var US_STATE_CODES = [
|
|
@@ -853,6 +856,7 @@ var $providerBoundStepResponse = obj({
|
|
|
853
856
|
provider: $provider,
|
|
854
857
|
transitions: z.array($transition),
|
|
855
858
|
preparedPayment: $preparedPayment.optional(),
|
|
859
|
+
handoff: obj({ provider: $provider, termsAcceptance: obj({ version: z.string().min(1) }).optional() }).optional(),
|
|
856
860
|
routingSessionRef: z.string().optional(),
|
|
857
861
|
providerAuthToken: obj({
|
|
858
862
|
clientSecret: z.string(),
|
|
@@ -868,6 +872,27 @@ var $providerBoundStepResponse = obj({
|
|
|
868
872
|
message: "preparedPayment.surface.provider must match the response provider"
|
|
869
873
|
});
|
|
870
874
|
}
|
|
875
|
+
if (response.handoff !== void 0 && response.handoff.provider !== response.provider) {
|
|
876
|
+
context.addIssue({
|
|
877
|
+
code: "custom",
|
|
878
|
+
path: ["handoff", "provider"],
|
|
879
|
+
message: "handoff.provider must match the response provider"
|
|
880
|
+
});
|
|
881
|
+
}
|
|
882
|
+
if (response.handoff !== void 0 && response.state.kind !== "QUOTE") {
|
|
883
|
+
context.addIssue({
|
|
884
|
+
code: "custom",
|
|
885
|
+
path: ["handoff"],
|
|
886
|
+
message: "only a QUOTE response hands off to a provider"
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
if (response.handoff !== void 0 && response.transitions.length > 0) {
|
|
890
|
+
context.addIssue({
|
|
891
|
+
code: "custom",
|
|
892
|
+
path: ["transitions"],
|
|
893
|
+
message: "a handoff response carries no transitions"
|
|
894
|
+
});
|
|
895
|
+
}
|
|
871
896
|
});
|
|
872
897
|
var $blockedStepResponse = obj({
|
|
873
898
|
state: $blockedState,
|
|
@@ -1948,6 +1973,69 @@ function assertFixture(id) {
|
|
|
1948
1973
|
function assertAllFixtures() {
|
|
1949
1974
|
return FIXTURES.map((meta) => assertFixture(meta.id));
|
|
1950
1975
|
}
|
|
1976
|
+
|
|
1977
|
+
// src/providers/moonpay.schemas.ts
|
|
1978
|
+
import { z as z2 } from "zod";
|
|
1979
|
+
var FIAT_CURRENCY_CODES2 = Object.keys(FIAT_CURRENCY_NAMES);
|
|
1980
|
+
var obj2 = (shape) => z2.object(shape).strict();
|
|
1981
|
+
var $nonEmpty = z2.string().refine((value) => value.trim().length > 0, "must not be blank");
|
|
1982
|
+
var $startRequest = obj2({
|
|
1983
|
+
amount: FiatAmountSchema,
|
|
1984
|
+
destination: obj2({ asset: $nonEmpty, network: $nonEmpty }),
|
|
1985
|
+
paymentMethod: z2.literal("apple_pay"),
|
|
1986
|
+
geo: obj2({ alpha2: z2.string().regex(/^[A-Z]{2}$/), region: $nonEmpty.optional(), ip: $nonEmpty.optional() }),
|
|
1987
|
+
termsAcceptance: obj2({ version: $nonEmpty, acceptedAt: z2.string().datetime({ offset: true }) })
|
|
1988
|
+
});
|
|
1989
|
+
var MoonPayStartRequestSchema = $startRequest;
|
|
1990
|
+
var $quoteInput = obj2({
|
|
1991
|
+
source: obj2({ asset: obj2({ code: z2.enum(FIAT_CURRENCY_CODES2) }), amount: $nonEmpty }),
|
|
1992
|
+
destination: obj2({ asset: obj2({ code: $nonEmpty }) }),
|
|
1993
|
+
wallet: obj2({ address: $nonEmpty }),
|
|
1994
|
+
paymentMethod: obj2({ type: z2.literal("apple_pay") }),
|
|
1995
|
+
feeBehavior: z2.literal("inclusive")
|
|
1996
|
+
});
|
|
1997
|
+
var $startResponse = obj2({ sessionToken: $nonEmpty, quoteInput: $quoteInput });
|
|
1998
|
+
var MoonPayStartResponseSchema = $startResponse;
|
|
1999
|
+
var $intentRequest = obj2({ customerId: $nonEmpty, accessToken: $nonEmpty });
|
|
2000
|
+
var MoonPayIntentRequestSchema = $intentRequest;
|
|
2001
|
+
var $refusal = z2.enum(["DOCUMENTS_REQUIRED", "FINAL_REJECTION", "CUSTOMER_MISMATCH"]);
|
|
2002
|
+
var $standing = z2.discriminatedUnion("status", [
|
|
2003
|
+
obj2({ status: z2.literal("READY"), orderId: $nonEmpty }),
|
|
2004
|
+
obj2({ status: z2.literal("KYC"), form: FormDescriptorSchema }),
|
|
2005
|
+
obj2({ status: z2.literal("PENDING"), retryAfterMs: z2.number().int().positive().max(6e4) }),
|
|
2006
|
+
obj2({ status: z2.literal("REFUSED"), reason: $refusal, recovery: z2.enum(["REQUOTE", "NONE"]) })
|
|
2007
|
+
]);
|
|
2008
|
+
var MoonPayStandingSchema = $standing;
|
|
2009
|
+
var MoonPayIntentResponseSchema = $standing;
|
|
2010
|
+
var $kycRequest = obj2({ formId: $nonEmpty, values: z2.record(z2.string(), z2.string()) });
|
|
2011
|
+
var MoonPayKycRequestSchema = $kycRequest;
|
|
2012
|
+
var $kycResponse = obj2({ status: z2.literal("ACCEPTED") });
|
|
2013
|
+
var MoonPayKycResponseSchema = $kycResponse;
|
|
2014
|
+
var $completeRequest = obj2({ orderId: $nonEmpty, transactionId: $nonEmpty });
|
|
2015
|
+
var MoonPayCompleteRequestSchema = $completeRequest;
|
|
2016
|
+
var MoonPayCompleteResponseSchema = FiatStepResponseSchema;
|
|
2017
|
+
var $fieldError = obj2({ fieldId: $nonEmpty, message: $nonEmpty });
|
|
2018
|
+
var $faultFields = {
|
|
2019
|
+
reason: z2.enum([
|
|
2020
|
+
"NOT_ELIGIBLE",
|
|
2021
|
+
"SESSION_BUDGET_SPENT",
|
|
2022
|
+
"PROVIDER_UNAVAILABLE",
|
|
2023
|
+
"INVALID_VALUE",
|
|
2024
|
+
"STALE_FORM",
|
|
2025
|
+
"TRANSACTION_NOT_VISIBLE",
|
|
2026
|
+
"WALLET_MISMATCH"
|
|
2027
|
+
]),
|
|
2028
|
+
recovery: z2.enum(["RETRY", "REFRESH", "REQUOTE", "NONE"]),
|
|
2029
|
+
fields: z2.array($fieldError).min(1).optional()
|
|
2030
|
+
};
|
|
2031
|
+
var fieldsOnlyOnInvalidValue = (fault) => fault.reason === "INVALID_VALUE" === (fault.fields !== void 0);
|
|
2032
|
+
var $fault = obj2($faultFields).refine(fieldsOnlyOnInvalidValue, "fields is present exactly when reason is INVALID_VALUE");
|
|
2033
|
+
var MoonPayFaultSchema = $fault;
|
|
2034
|
+
var $errorBody = obj2({ ...$faultFields, errorCode: $nonEmpty, errorMsg: z2.string(), reqId: z2.string().optional() }).refine(
|
|
2035
|
+
fieldsOnlyOnInvalidValue,
|
|
2036
|
+
"fields is present exactly when reason is INVALID_VALUE"
|
|
2037
|
+
);
|
|
2038
|
+
var MoonPayErrorBodySchema = $errorBody;
|
|
1951
2039
|
export {
|
|
1952
2040
|
AuthChallengeSchema,
|
|
1953
2041
|
BlockedReasonSchema,
|
|
@@ -1988,6 +2076,18 @@ export {
|
|
|
1988
2076
|
KycInputRequiredStateSchema,
|
|
1989
2077
|
KycNoActionRequiredStateSchema,
|
|
1990
2078
|
KycSdkResultReportSchema,
|
|
2079
|
+
MOONPAY_ENDPOINTS,
|
|
2080
|
+
MoonPayCompleteRequestSchema,
|
|
2081
|
+
MoonPayCompleteResponseSchema,
|
|
2082
|
+
MoonPayErrorBodySchema,
|
|
2083
|
+
MoonPayFaultSchema,
|
|
2084
|
+
MoonPayIntentRequestSchema,
|
|
2085
|
+
MoonPayIntentResponseSchema,
|
|
2086
|
+
MoonPayKycRequestSchema,
|
|
2087
|
+
MoonPayKycResponseSchema,
|
|
2088
|
+
MoonPayStandingSchema,
|
|
2089
|
+
MoonPayStartRequestSchema,
|
|
2090
|
+
MoonPayStartResponseSchema,
|
|
1991
2091
|
OrderAwaitingConfirmationStateSchema,
|
|
1992
2092
|
OrderCreatedStateSchema,
|
|
1993
2093
|
OrderRefSchema,
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MoonPay provider-owned flow: `POST /fiat/providers/moonpay/{start,intent,kyc,complete}`.
|
|
3
|
+
*
|
|
4
|
+
* Only `intent` decides what happens next. `kyc` confirms a write or rejects it with field errors,
|
|
5
|
+
* and the client then calls `intent` again. Identity and the deposit wallet always come from the
|
|
6
|
+
* verified partner assertion, never from a request body.
|
|
7
|
+
*
|
|
8
|
+
* A fault is a 4xx/5xx whose body is the shared error body plus `MoonPayFault`. A decision the user
|
|
9
|
+
* can act on is a 200 `MoonPayStanding`.
|
|
10
|
+
*
|
|
11
|
+
* Zero runtime dependencies, so production React Native code can import it. The zod schemas are in
|
|
12
|
+
* `./moonpay.schemas`, exported from the package root.
|
|
13
|
+
*/
|
|
14
|
+
import type { FiatCurrencyCode } from '../codes';
|
|
15
|
+
import type { FiatAmount, FiatStepResponse, FormDescriptor, TermsAcceptance } from '../types';
|
|
16
|
+
export declare const MOONPAY_ENDPOINTS: {
|
|
17
|
+
readonly start: "POST /fiat/providers/moonpay/start";
|
|
18
|
+
readonly intent: "POST /fiat/providers/moonpay/intent";
|
|
19
|
+
readonly kyc: "POST /fiat/providers/moonpay/kyc";
|
|
20
|
+
readonly complete: "POST /fiat/providers/moonpay/complete";
|
|
21
|
+
};
|
|
22
|
+
export interface MoonPayStartRequest {
|
|
23
|
+
amount: FiatAmount;
|
|
24
|
+
/** The quote's `crypto.currency` and `crypto.network`, unchanged. */
|
|
25
|
+
destination: {
|
|
26
|
+
asset: string;
|
|
27
|
+
network: string;
|
|
28
|
+
};
|
|
29
|
+
paymentMethod: 'apple_pay';
|
|
30
|
+
/** The geo endpoint's response, as sent to `POST /fiat/quote`. `alpha2` is ISO 3166-1 alpha-2. */
|
|
31
|
+
geo: {
|
|
32
|
+
alpha2: string;
|
|
33
|
+
region?: string;
|
|
34
|
+
ip?: string;
|
|
35
|
+
};
|
|
36
|
+
/** The MoonPay terms notice on the amount screen; the tap is the acceptance. */
|
|
37
|
+
termsAcceptance: TermsAcceptance;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The parameters for the device `client.getQuote`, not a quote. The backend builds them because the
|
|
41
|
+
* wallet must be the verified one and MoonPay's currency codes differ by environment.
|
|
42
|
+
*/
|
|
43
|
+
export interface MoonPayQuoteInput {
|
|
44
|
+
source: {
|
|
45
|
+
asset: {
|
|
46
|
+
code: FiatCurrencyCode;
|
|
47
|
+
};
|
|
48
|
+
amount: string;
|
|
49
|
+
};
|
|
50
|
+
destination: {
|
|
51
|
+
asset: {
|
|
52
|
+
code: string;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
wallet: {
|
|
56
|
+
address: string;
|
|
57
|
+
};
|
|
58
|
+
paymentMethod: {
|
|
59
|
+
type: 'apple_pay';
|
|
60
|
+
};
|
|
61
|
+
feeBehavior: 'inclusive';
|
|
62
|
+
}
|
|
63
|
+
export interface MoonPayStartResponse {
|
|
64
|
+
/** The one SDK session, for the connection check, the auth frames, and the Apple Pay button. */
|
|
65
|
+
sessionToken: string;
|
|
66
|
+
quoteInput: MoonPayQuoteInput;
|
|
67
|
+
}
|
|
68
|
+
export interface MoonPayIntentRequest {
|
|
69
|
+
/** From the SDK's `active` connection. */
|
|
70
|
+
customerId: string;
|
|
71
|
+
/** From the SDK's `active` connection. A credential: the backend strips it from every log. */
|
|
72
|
+
accessToken: string;
|
|
73
|
+
}
|
|
74
|
+
export type MoonPayRefusal = 'DOCUMENTS_REQUIRED' | 'FINAL_REJECTION' | 'CUSTOMER_MISMATCH';
|
|
75
|
+
export type MoonPayStanding =
|
|
76
|
+
/** `orderId` is the `externalTransactionId` for the Apple Pay button. */
|
|
77
|
+
{
|
|
78
|
+
status: 'READY';
|
|
79
|
+
orderId: string;
|
|
80
|
+
} | {
|
|
81
|
+
status: 'KYC';
|
|
82
|
+
form: FormDescriptor;
|
|
83
|
+
} | {
|
|
84
|
+
status: 'PENDING';
|
|
85
|
+
retryAfterMs: number;
|
|
86
|
+
} | {
|
|
87
|
+
status: 'REFUSED';
|
|
88
|
+
reason: MoonPayRefusal;
|
|
89
|
+
recovery: 'REQUOTE' | 'NONE';
|
|
90
|
+
};
|
|
91
|
+
export type MoonPayIntentResponse = MoonPayStanding;
|
|
92
|
+
export interface MoonPayKycRequest {
|
|
93
|
+
/** From the `KYC` standing. A stale one is a 409 `STALE_FORM` with recovery `REFRESH`. */
|
|
94
|
+
formId: string;
|
|
95
|
+
/** One string per form field id. */
|
|
96
|
+
values: Record<string, string>;
|
|
97
|
+
}
|
|
98
|
+
/** The write landed. The client calls `intent` next. */
|
|
99
|
+
export interface MoonPayKycResponse {
|
|
100
|
+
status: 'ACCEPTED';
|
|
101
|
+
}
|
|
102
|
+
export interface MoonPayCompleteRequest {
|
|
103
|
+
orderId: string;
|
|
104
|
+
/** From the Apple Pay completion event. */
|
|
105
|
+
transactionId: string;
|
|
106
|
+
}
|
|
107
|
+
/** The same response as `GET /fiat/orders/:orderId`, so the shared order screen renders it. */
|
|
108
|
+
export type MoonPayCompleteResponse = FiatStepResponse;
|
|
109
|
+
/**
|
|
110
|
+
* `RETRY` sends the same request again. `REFRESH` calls `intent` for a new standing. `REQUOTE` goes
|
|
111
|
+
* back to `POST /fiat/quote`. `NONE` ends the flow.
|
|
112
|
+
*/
|
|
113
|
+
export type MoonPayRecovery = 'RETRY' | 'REFRESH' | 'REQUOTE' | 'NONE';
|
|
114
|
+
export type MoonPayFaultReason = 'NOT_ELIGIBLE' | 'SESSION_BUDGET_SPENT' | 'PROVIDER_UNAVAILABLE' | 'INVALID_VALUE' | 'STALE_FORM' | 'TRANSACTION_NOT_VISIBLE' | 'WALLET_MISMATCH';
|
|
115
|
+
export interface MoonPayFieldError {
|
|
116
|
+
fieldId: string;
|
|
117
|
+
message: string;
|
|
118
|
+
}
|
|
119
|
+
/** The fields a MoonPay route adds to the shared error body. `fields` is only on `INVALID_VALUE`. */
|
|
120
|
+
export interface MoonPayFault {
|
|
121
|
+
reason: MoonPayFaultReason;
|
|
122
|
+
recovery: MoonPayRecovery;
|
|
123
|
+
fields?: MoonPayFieldError[];
|
|
124
|
+
}
|
|
125
|
+
/** A MoonPay route's 4xx/5xx body: the shared error body plus `MoonPayFault`. */
|
|
126
|
+
export type MoonPayErrorBody = MoonPayFault & {
|
|
127
|
+
errorCode: string;
|
|
128
|
+
errorMsg: string;
|
|
129
|
+
reqId?: string;
|
|
130
|
+
};
|
|
131
|
+
//# sourceMappingURL=moonpay.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/providers/moonpay.ts
|
|
21
|
+
var moonpay_exports = {};
|
|
22
|
+
__export(moonpay_exports, {
|
|
23
|
+
MOONPAY_ENDPOINTS: () => MOONPAY_ENDPOINTS
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(moonpay_exports);
|
|
26
|
+
var MOONPAY_ENDPOINTS = {
|
|
27
|
+
start: "POST /fiat/providers/moonpay/start",
|
|
28
|
+
intent: "POST /fiat/providers/moonpay/intent",
|
|
29
|
+
kyc: "POST /fiat/providers/moonpay/kyc",
|
|
30
|
+
complete: "POST /fiat/providers/moonpay/complete"
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=moonpay.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* zod schemas for the MoonPay provider-owned flow. Test-time and backend-boundary only: exported from
|
|
3
|
+
* the package root, never from `./moonpay`, so the production entry stays free of zod.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import type { MoonPayCompleteRequest, MoonPayCompleteResponse, MoonPayErrorBody, MoonPayFault, MoonPayIntentRequest, MoonPayIntentResponse, MoonPayKycRequest, MoonPayKycResponse, MoonPayStanding, MoonPayStartRequest, MoonPayStartResponse } from './moonpay';
|
|
7
|
+
export declare const MoonPayStartRequestSchema: z.ZodType<MoonPayStartRequest>;
|
|
8
|
+
export declare const MoonPayStartResponseSchema: z.ZodType<MoonPayStartResponse>;
|
|
9
|
+
export declare const MoonPayIntentRequestSchema: z.ZodType<MoonPayIntentRequest>;
|
|
10
|
+
export declare const MoonPayStandingSchema: z.ZodType<MoonPayStanding>;
|
|
11
|
+
export declare const MoonPayIntentResponseSchema: z.ZodType<MoonPayIntentResponse>;
|
|
12
|
+
export declare const MoonPayKycRequestSchema: z.ZodType<MoonPayKycRequest>;
|
|
13
|
+
export declare const MoonPayKycResponseSchema: z.ZodType<MoonPayKycResponse>;
|
|
14
|
+
export declare const MoonPayCompleteRequestSchema: z.ZodType<MoonPayCompleteRequest>;
|
|
15
|
+
export declare const MoonPayCompleteResponseSchema: z.ZodType<MoonPayCompleteResponse>;
|
|
16
|
+
export declare const MoonPayFaultSchema: z.ZodType<MoonPayFault>;
|
|
17
|
+
export declare const MoonPayErrorBodySchema: z.ZodType<MoonPayErrorBody>;
|
|
18
|
+
//# sourceMappingURL=moonpay.schemas.d.ts.map
|
package/dist/table.js
CHANGED
package/dist/table.mjs
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -714,6 +714,17 @@ export type FiatStepResponse = (FiatStepResponseBase & {
|
|
|
714
714
|
provider: FiatProvider;
|
|
715
715
|
/** Optional future payment artifact; never one of this response's currently active transitions. */
|
|
716
716
|
preparedPayment?: PreparedPayment;
|
|
717
|
+
/**
|
|
718
|
+
* The provider runs its own flow from here (`POST /fiat/providers/{provider}/…`). Present only
|
|
719
|
+
* when the request's `handoffs` named this provider; the response then carries no transitions.
|
|
720
|
+
*/
|
|
721
|
+
handoff?: {
|
|
722
|
+
provider: FiatProvider;
|
|
723
|
+
/** The terms revision the provider's `start` records; echo it in `termsAcceptance.version`. */
|
|
724
|
+
termsAcceptance?: {
|
|
725
|
+
version: string;
|
|
726
|
+
};
|
|
727
|
+
};
|
|
717
728
|
});
|
|
718
729
|
export {};
|
|
719
730
|
//# sourceMappingURL=types.d.ts.map
|
package/moonpay.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/providers/moonpay';
|
package/moonpay.js
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fun-xyz/fiat-contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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": {
|
|
@@ -28,6 +28,11 @@
|
|
|
28
28
|
"import": "./dist/table.mjs",
|
|
29
29
|
"require": "./dist/table.js"
|
|
30
30
|
},
|
|
31
|
+
"./moonpay": {
|
|
32
|
+
"types": "./dist/providers/moonpay.d.ts",
|
|
33
|
+
"import": "./dist/providers/moonpay.mjs",
|
|
34
|
+
"require": "./dist/providers/moonpay.js"
|
|
35
|
+
},
|
|
31
36
|
"./package.json": "./package.json"
|
|
32
37
|
},
|
|
33
38
|
"files": [
|
|
@@ -36,6 +41,8 @@
|
|
|
36
41
|
"table.d.ts",
|
|
37
42
|
"types.js",
|
|
38
43
|
"types.d.ts",
|
|
44
|
+
"moonpay.js",
|
|
45
|
+
"moonpay.d.ts",
|
|
39
46
|
"README.md",
|
|
40
47
|
"!dist/**/*.map"
|
|
41
48
|
],
|
|
@@ -75,6 +82,9 @@
|
|
|
75
82
|
],
|
|
76
83
|
"table": [
|
|
77
84
|
"./dist/table.d.ts"
|
|
85
|
+
],
|
|
86
|
+
"moonpay": [
|
|
87
|
+
"./dist/providers/moonpay.d.ts"
|
|
78
88
|
]
|
|
79
89
|
}
|
|
80
90
|
}
|