@fun-xyz/fiat-contract 0.7.0 → 0.8.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/index.js CHANGED
@@ -387,7 +387,7 @@ var HTTP_VERBS = ["GET", "POST"];
387
387
  var ENDPOINT_PATTERN = /^(GET|POST) \/fiat\/[^\s]*$/;
388
388
  var $endpoint = import_zod.z.string().regex(ENDPOINT_PATTERN, 'endpoint must read "<GET|POST> /fiat/\u2026"');
389
389
  var FiatEndpointSchema = $endpoint;
390
- var $provider = import_zod.z.enum(["TRANSAK", "SWAPPED", "BANXA"]);
390
+ var $provider = import_zod.z.enum(["TRANSAK", "SWAPPED", "BANXA", "MOONPAY", "STRIPE"]);
391
391
  var FiatProviderSchema = $provider;
392
392
  var $kycProvider = import_zod.z.enum(["SUMSUB"]);
393
393
  var KYCProviderSchema = $kycProvider;
@@ -484,7 +484,7 @@ var $refund = obj({
484
484
  expectedBy: import_zod.z.string()
485
485
  });
486
486
  var RefundSchema = $refund;
487
- var $surfaceKind = import_zod.z.enum(["URL_REDIRECT", "URL_EMBED", "PCI_COMPONENT", "PAY_SHEET", "ACH_COMPONENT"]);
487
+ var $surfaceKind = import_zod.z.enum(["URL_REDIRECT", "KYC_SDK", "PCI_COMPONENT", "PAY_SHEET", "ACH_COMPONENT"]);
488
488
  var SurfaceKindSchema = $surfaceKind;
489
489
  var $surface = obj({
490
490
  kind: $surfaceKind,
@@ -649,6 +649,7 @@ var SessionAuthStateSchema = $sessionAuthState;
649
649
  var $kycCaptureState = obj({
650
650
  kind: import_zod.z.literal("KYC"),
651
651
  phase: import_zod.z.literal("CAPTURE"),
652
+ quote: $quote,
652
653
  surface: $surface,
653
654
  error: $failureReason.optional()
654
655
  });
@@ -656,6 +657,7 @@ var KycCaptureStateSchema = $kycCaptureState;
656
657
  var $kycInputRequiredState = obj({
657
658
  kind: import_zod.z.literal("KYC"),
658
659
  phase: import_zod.z.literal("INPUT_REQUIRED"),
660
+ quote: $quote,
659
661
  form: $formDescriptor,
660
662
  error: $failureReason.optional()
661
663
  });
@@ -663,6 +665,7 @@ var KycInputRequiredStateSchema = $kycInputRequiredState;
663
665
  var $kycNoActionRequiredState = obj({
664
666
  kind: import_zod.z.literal("KYC"),
665
667
  phase: import_zod.z.literal("NO_ACTION_REQUIRED"),
668
+ quote: $quote,
666
669
  reason: import_zod.z.enum(["IN_REVIEW", "ON_HOLD", "REJECTED"]),
667
670
  retryAfter: import_zod.z.string().optional(),
668
671
  failureReason: $failureReason.optional(),
@@ -740,7 +743,7 @@ var $stepResponse = obj({
740
743
  var FiatStepResponseSchema = $stepResponse;
741
744
 
742
745
  // package.json
743
- var version = "0.7.0";
746
+ var version = "0.8.0";
744
747
 
745
748
  // src/table.ts
746
749
  var TABLE_VERSION = version;
@@ -866,21 +869,23 @@ var TRANSITION_TABLE = {
866
869
  {
867
870
  id: "capture",
868
871
  mode: "CLIENT_SURFACE",
869
- endpoint: "GET /fiat/kyc",
870
- note: 'report target per FE bindings ("POST surface report \u2192 GET /fiat/kyc") and contract Flow C.'
872
+ endpoint: "POST /fiat/kyc/capture",
873
+ note: "Reports SDK submission; provider eligibility is re-evaluated through quote orchestration."
871
874
  }
872
875
  ],
873
876
  mayReturn: [
877
+ "KYC/CAPTURE",
874
878
  "KYC/INPUT_REQUIRED",
875
879
  "KYC/NO_ACTION_REQUIRED:IN_REVIEW",
876
880
  "KYC/NO_ACTION_REQUIRED:ON_HOLD",
877
881
  "KYC/NO_ACTION_REQUIRED:REJECTED",
882
+ "QUOTE",
883
+ "PAYMENT/CAPTURE",
884
+ "PAYMENT/INSTRUCT",
878
885
  "ORDER/AWAITING_CONFIRMATION"
879
886
  ],
880
887
  terminal: false,
881
- notes: [
882
- "Dropped from v1 (no UK headless-module coverage) \u2014 FE Screen 8 is a tombstone. Kind retained as vocabulary; the handshake (supportedStepKinds) keeps the backend from routing v1 SDKs here."
883
- ]
888
+ notes: ["Carries the handshake-gated KYC_SDK surface; provider selects the identity-vendor adapter."]
884
889
  },
885
890
  "KYC/INPUT_REQUIRED": {
886
891
  key: "KYC/INPUT_REQUIRED",
@@ -892,16 +897,20 @@ var TRANSITION_TABLE = {
892
897
  { id: "submit_round", mode: "SUBMIT", endpoint: "POST /fiat/kyc/form" }
893
898
  ],
894
899
  mayReturn: [
900
+ "KYC/CAPTURE",
895
901
  "KYC/INPUT_REQUIRED",
896
902
  "KYC/NO_ACTION_REQUIRED:IN_REVIEW",
897
903
  "KYC/NO_ACTION_REQUIRED:ON_HOLD",
898
904
  "KYC/NO_ACTION_REQUIRED:REJECTED",
905
+ "QUOTE",
906
+ "PAYMENT/CAPTURE",
907
+ "PAYMENT/INSTRUCT",
899
908
  "ORDER/AWAITING_CONFIRMATION"
900
909
  ],
901
910
  terminal: false,
902
911
  notes: [
903
912
  "One POST per round; conditional requirements may open another round.",
904
- "FILE fields stream to POST /fiat/kyc/document \u2014 an upload path the harness owns, not a transition.",
913
+ "FILE fields use POST /fiat/kyc/document to obtain or report a direct provider/vendor upload; document bytes never transit Fun. The harness owns this auxiliary path, not a transition.",
905
914
  "Hosted KYC links arrive as HOSTED_LINK form fields, not as a Surface."
906
915
  ]
907
916
  },
@@ -912,12 +921,16 @@ var TRANSITION_TABLE = {
912
921
  reason: "IN_REVIEW",
913
922
  screens: [9],
914
923
  docStatus: "SPECIFIED",
915
- allowedTransitions: [{ id: "poll", mode: "AWAIT", endpoint: "GET /fiat/kyc" }],
924
+ allowedTransitions: [{ id: "poll", mode: "AWAIT", endpoint: "GET /fiat/quotes/:quoteRef" }],
916
925
  mayReturn: [
917
926
  "KYC/NO_ACTION_REQUIRED:IN_REVIEW",
927
+ "KYC/CAPTURE",
918
928
  "KYC/INPUT_REQUIRED",
919
929
  "KYC/NO_ACTION_REQUIRED:ON_HOLD",
920
930
  "KYC/NO_ACTION_REQUIRED:REJECTED",
931
+ "QUOTE",
932
+ "PAYMENT/CAPTURE",
933
+ "PAYMENT/INSTRUCT",
921
934
  "ORDER/AWAITING_CONFIRMATION"
922
935
  ],
923
936
  terminal: false,
@@ -947,20 +960,11 @@ var TRANSITION_TABLE = {
947
960
  reason: "REJECTED",
948
961
  screens: [11],
949
962
  docStatus: "SPECIFIED",
950
- allowedTransitions: [
951
- {
952
- id: "escalate",
953
- mode: "SUBMIT",
954
- endpoint: "GET /fiat/kyc",
955
- when: "an escalation round is offered",
956
- note: "TODO(open-decision): placeholder shape \u2014 the FE doc flags that a GET carrying params is not a real request shape, and OQ7 owns which rejections escalate. FE doc open question 7."
957
- }
958
- ],
959
- mayReturn: KYC_ANY,
960
- terminal: false,
963
+ allowedTransitions: [],
964
+ mayReturn: [],
965
+ terminal: true,
961
966
  notes: [
962
- "Terminal *variant*: failureReason {KYC_REJECTED, retryable: false, recovery: CONTACT_SUPPORT} + transitions [] \u2014 renders in place, never routes through ORDER{CREATED, FAILED}. Because escalation is also legal here, the entry is not flatly terminal.",
963
- "TODO(open-decision): contract OQ7 \u2014 terminal vs escalating rejections are not enumerated."
967
+ "Only explicit non-retryable outcomes reach REJECTED. Correctable failures return CAPTURE or INPUT_REQUIRED; provider-specific declines re-route before becoming user rejection."
964
968
  ]
965
969
  },
966
970
  PENDING_ORDER: {
@@ -1122,8 +1126,10 @@ var DOCUMENTED_ENDPOINTS = [
1122
1126
  "POST /fiat/payment-session",
1123
1127
  "POST /fiat/session",
1124
1128
  "POST /fiat/session/verify",
1125
- "GET /fiat/kyc",
1129
+ "GET /fiat/quotes/:quoteRef",
1126
1130
  "POST /fiat/kyc/form",
1131
+ "POST /fiat/kyc/capture",
1132
+ "POST /fiat/kyc/sdk-token",
1127
1133
  "POST /fiat/kyc/document",
1128
1134
  "POST /fiat/instruments",
1129
1135
  "POST /fiat/orders",
@@ -1135,13 +1141,17 @@ var DOCUMENTED_ENDPOINTS = [
1135
1141
  "POST /fiat/orders/:id/surface-result"
1136
1142
  ];
1137
1143
  var UNOFFERED_ENDPOINTS = [
1144
+ {
1145
+ endpoint: "POST /fiat/kyc/sdk-token",
1146
+ reason: "SDK token refresh is adapter-driven rather than a flow transition."
1147
+ },
1138
1148
  {
1139
1149
  endpoint: "GET /fiat/payment-methods",
1140
1150
  reason: "Discovery, called before any flow state exists \u2014 there is no state to hang it off."
1141
1151
  },
1142
1152
  {
1143
1153
  endpoint: "POST /fiat/kyc/document",
1144
- reason: "FILE fields stream to it directly; the harness owns that upload path and it is not a transition (see KYC/INPUT_REQUIRED notes)."
1154
+ reason: "FILE fields use it for a direct provider/vendor upload handshake and completion report; the harness owns that auxiliary path and it is not a transition (see KYC/INPUT_REQUIRED notes)."
1145
1155
  },
1146
1156
  {
1147
1157
  endpoint: "POST /fiat/instruments",
@@ -1349,45 +1359,43 @@ var FIXTURE_DATA = {
1349
1359
  "state": {
1350
1360
  "kind": "KYC",
1351
1361
  "phase": "INPUT_REQUIRED",
1362
+ "quote": {
1363
+ "quoteRef": "q_8f2",
1364
+ "fiat": {
1365
+ "currency": "GBP",
1366
+ "amount": "100.00"
1367
+ },
1368
+ "crypto": {
1369
+ "currency": "USDC",
1370
+ "network": "polygon",
1371
+ "amount": "98.41"
1372
+ },
1373
+ "rate": "0.9841",
1374
+ "totalFee": "1.59",
1375
+ "feeBreakdown": [
1376
+ {
1377
+ "id": "provider_fee",
1378
+ "labelFallback": "Processing fee",
1379
+ "amount": "1.59"
1380
+ }
1381
+ ],
1382
+ "paymentMethod": "bank_transfer",
1383
+ "expiresAt": "\u2026"
1384
+ },
1352
1385
  "form": {
1353
- "formId": "personal_details",
1386
+ "formId": "kyc_q_8f2_1",
1354
1387
  "fields": [
1355
1388
  {
1356
- "id": "firstName",
1389
+ "id": "tin",
1357
1390
  "type": "TEXT",
1358
- "labelFallback": "First name",
1391
+ "labelFallback": "Tax ID",
1359
1392
  "required": true
1360
1393
  },
1361
1394
  {
1362
- "id": "dob",
1363
- "type": "DATE",
1364
- "labelFallback": "Date of birth",
1365
- "required": true
1366
- },
1367
- {
1368
- "id": "country",
1369
- "type": "COUNTRY",
1370
- "labelFallback": "Country",
1395
+ "id": "address",
1396
+ "type": "TEXT",
1397
+ "labelFallback": "Home address",
1371
1398
  "required": true
1372
- },
1373
- {
1374
- "id": "sourceOfFunds",
1375
- "type": "SELECT",
1376
- "labelFallback": "Source of funds",
1377
- "required": true,
1378
- "options": [
1379
- {
1380
- "id": "salary",
1381
- "labelFallback": "Salary"
1382
- }
1383
- ]
1384
- },
1385
- {
1386
- "id": "idProof",
1387
- "type": "HOSTED_LINK",
1388
- "labelFallback": "Verify your ID",
1389
- "required": true,
1390
- "url": "\u2026"
1391
1399
  }
1392
1400
  ]
1393
1401
  }
@@ -1399,7 +1407,8 @@ var FIXTURE_DATA = {
1399
1407
  "mode": "SUBMIT",
1400
1408
  "endpoint": "POST /fiat/kyc/form",
1401
1409
  "params": {
1402
- "formId": "personal_details"
1410
+ "quoteRef": "q_8f2",
1411
+ "formId": "kyc_q_8f2_1"
1403
1412
  },
1404
1413
  "inputs": {
1405
1414
  "values": {
@@ -1484,11 +1493,84 @@ var FIXTURE_DATA = {
1484
1493
  }
1485
1494
  ]
1486
1495
  },
1496
+ "screen-08-kyc-capture": {
1497
+ "state": {
1498
+ "kind": "KYC",
1499
+ "phase": "CAPTURE",
1500
+ "quote": {
1501
+ "quoteRef": "q_8f2",
1502
+ "fiat": {
1503
+ "currency": "GBP",
1504
+ "amount": "100.00"
1505
+ },
1506
+ "crypto": {
1507
+ "currency": "USDC",
1508
+ "network": "polygon",
1509
+ "amount": "98.41"
1510
+ },
1511
+ "rate": "0.9841",
1512
+ "totalFee": "1.59",
1513
+ "feeBreakdown": [
1514
+ {
1515
+ "id": "provider_fee",
1516
+ "labelFallback": "Processing fee",
1517
+ "amount": "1.59"
1518
+ }
1519
+ ],
1520
+ "paymentMethod": "bank_transfer",
1521
+ "expiresAt": "\u2026"
1522
+ },
1523
+ "surface": {
1524
+ "kind": "KYC_SDK",
1525
+ "provider": "SUMSUB",
1526
+ "params": {
1527
+ "accessToken": "eyJ\u2026"
1528
+ },
1529
+ "expiresAt": "\u2026"
1530
+ }
1531
+ },
1532
+ "provider": "TRANSAK",
1533
+ "transitions": [
1534
+ {
1535
+ "id": "capture",
1536
+ "mode": "CLIENT_SURFACE",
1537
+ "report": {
1538
+ "endpoint": "POST /fiat/kyc/capture",
1539
+ "params": {
1540
+ "quoteRef": "q_8f2"
1541
+ }
1542
+ }
1543
+ }
1544
+ ]
1545
+ },
1487
1546
  "screen-09-kyc-in-review": {
1488
1547
  "state": {
1489
1548
  "kind": "KYC",
1490
1549
  "phase": "NO_ACTION_REQUIRED",
1491
- "reason": "IN_REVIEW"
1550
+ "reason": "IN_REVIEW",
1551
+ "quote": {
1552
+ "quoteRef": "q_8f2",
1553
+ "fiat": {
1554
+ "currency": "GBP",
1555
+ "amount": "100.00"
1556
+ },
1557
+ "crypto": {
1558
+ "currency": "USDC",
1559
+ "network": "polygon",
1560
+ "amount": "98.41"
1561
+ },
1562
+ "rate": "0.9841",
1563
+ "totalFee": "1.59",
1564
+ "feeBreakdown": [
1565
+ {
1566
+ "id": "provider_fee",
1567
+ "labelFallback": "Processing fee",
1568
+ "amount": "1.59"
1569
+ }
1570
+ ],
1571
+ "paymentMethod": "bank_transfer",
1572
+ "expiresAt": "\u2026"
1573
+ }
1492
1574
  },
1493
1575
  "provider": "TRANSAK",
1494
1576
  "transitions": [
@@ -1496,10 +1578,7 @@ var FIXTURE_DATA = {
1496
1578
  "id": "poll",
1497
1579
  "mode": "AWAIT",
1498
1580
  "poll": {
1499
- "endpoint": "GET /fiat/kyc",
1500
- "params": {
1501
- "quoteRef": "q_8f2"
1502
- },
1581
+ "endpoint": "GET /fiat/quotes/q_8f2",
1503
1582
  "intervalMs": 3e3,
1504
1583
  "backoffFactor": 1.5,
1505
1584
  "maxIntervalMs": 1e4,
@@ -1513,28 +1592,70 @@ var FIXTURE_DATA = {
1513
1592
  "kind": "KYC",
1514
1593
  "phase": "NO_ACTION_REQUIRED",
1515
1594
  "reason": "ON_HOLD",
1516
- "retryAfter": "2026-08-20T09:00:00Z"
1595
+ "retryAfter": "2026-08-20T09:00:00Z",
1596
+ "quote": {
1597
+ "quoteRef": "q_8f2",
1598
+ "fiat": {
1599
+ "currency": "GBP",
1600
+ "amount": "100.00"
1601
+ },
1602
+ "crypto": {
1603
+ "currency": "USDC",
1604
+ "network": "polygon",
1605
+ "amount": "98.41"
1606
+ },
1607
+ "rate": "0.9841",
1608
+ "totalFee": "1.59",
1609
+ "feeBreakdown": [
1610
+ {
1611
+ "id": "provider_fee",
1612
+ "labelFallback": "Processing fee",
1613
+ "amount": "1.59"
1614
+ }
1615
+ ],
1616
+ "paymentMethod": "bank_transfer",
1617
+ "expiresAt": "\u2026"
1618
+ }
1517
1619
  },
1518
1620
  "provider": "TRANSAK",
1519
1621
  "transitions": []
1520
1622
  },
1521
- "screen-11-kyc-rejected-escalation": {
1623
+ "screen-11-kyc-rejected": {
1522
1624
  "state": {
1523
1625
  "kind": "KYC",
1524
1626
  "phase": "NO_ACTION_REQUIRED",
1525
- "reason": "REJECTED"
1627
+ "reason": "REJECTED",
1628
+ "quote": {
1629
+ "quoteRef": "q_8f2",
1630
+ "fiat": {
1631
+ "currency": "GBP",
1632
+ "amount": "100.00"
1633
+ },
1634
+ "crypto": {
1635
+ "currency": "USDC",
1636
+ "network": "polygon",
1637
+ "amount": "98.41"
1638
+ },
1639
+ "rate": "0.9841",
1640
+ "totalFee": "1.59",
1641
+ "feeBreakdown": [
1642
+ {
1643
+ "id": "provider_fee",
1644
+ "labelFallback": "Processing fee",
1645
+ "amount": "1.59"
1646
+ }
1647
+ ],
1648
+ "paymentMethod": "bank_transfer",
1649
+ "expiresAt": "\u2026"
1650
+ },
1651
+ "failureReason": {
1652
+ "category": "KYC_REJECTED",
1653
+ "retryable": false,
1654
+ "recovery": "CONTACT_SUPPORT"
1655
+ }
1526
1656
  },
1527
1657
  "provider": "TRANSAK",
1528
- "transitions": [
1529
- {
1530
- "id": "escalate",
1531
- "mode": "SUBMIT",
1532
- "endpoint": "GET /fiat/kyc",
1533
- "params": {
1534
- "tier": "escalated"
1535
- }
1536
- }
1537
- ]
1658
+ "transitions": []
1538
1659
  },
1539
1660
  "screen-12-pending-order": {
1540
1661
  "state": {
@@ -1812,8 +1933,8 @@ var FIXTURES = [
1812
1933
  {
1813
1934
  id: "screen-03-kyc-input-required",
1814
1935
  file: "screen-03-kyc-input-required.json",
1815
- source: "FE_DOC",
1816
- docRef: "Screen 3 \xB7 Identity form (KYC)",
1936
+ source: "KYC_DOC",
1937
+ docRef: "Fiat KYC \xB7 L1 input round",
1817
1938
  screen: 3,
1818
1939
  stateKey: "KYC/INPUT_REQUIRED",
1819
1940
  notes: ["Carries the FORM_VALUES input spec \u2014 the no-double-carry case of the accepted split."]
@@ -1841,34 +1962,40 @@ var FIXTURES = [
1841
1962
  "TODO(open-decision): report target per card topology is a Transak ask (contract Flow A)."
1842
1963
  ]
1843
1964
  },
1965
+ {
1966
+ id: "screen-08-kyc-capture",
1967
+ file: "screen-08-kyc-capture.json",
1968
+ source: "KYC_DOC",
1969
+ docRef: "Fiat KYC \xB7 embedded Sumsub WebSDK",
1970
+ screen: 8,
1971
+ stateKey: "KYC/CAPTURE",
1972
+ notes: ["The client mounts the Sumsub adapter; no URL or iframe is emitted."]
1973
+ },
1844
1974
  {
1845
1975
  id: "screen-09-kyc-in-review",
1846
1976
  file: "screen-09-kyc-in-review.json",
1847
- source: "FE_DOC",
1848
- docRef: "Screen 9 \xB7 Verifying identity",
1977
+ source: "KYC_DOC",
1978
+ docRef: "Fiat KYC \xB7 pending quote",
1849
1979
  screen: 9,
1850
1980
  stateKey: "KYC/NO_ACTION_REQUIRED:IN_REVIEW"
1851
1981
  },
1852
1982
  {
1853
1983
  id: "screen-10-kyc-on-hold",
1854
1984
  file: "screen-10-kyc-on-hold.json",
1855
- source: "FE_DOC",
1856
- docRef: "Screen 10 \xB7 Verification on hold",
1985
+ source: "KYC_DOC",
1986
+ docRef: "Fiat KYC \xB7 verification on hold",
1857
1987
  screen: 10,
1858
1988
  stateKey: "KYC/NO_ACTION_REQUIRED:ON_HOLD",
1859
1989
  notes: ["transitions: [] and NOT terminal \u2014 the fixture that proves terminality is table data."]
1860
1990
  },
1861
1991
  {
1862
- id: "screen-11-kyc-rejected-escalation",
1863
- file: "screen-11-kyc-rejected-escalation.json",
1864
- source: "FE_DOC",
1865
- docRef: "Screen 11 \xB7 Verification unsuccessful",
1992
+ id: "screen-11-kyc-rejected",
1993
+ file: "screen-11-kyc-rejected.json",
1994
+ source: "KYC_DOC",
1995
+ docRef: "Fiat KYC \xB7 non-retryable rejection",
1866
1996
  screen: 11,
1867
1997
  stateKey: "KYC/NO_ACTION_REQUIRED:REJECTED",
1868
- notes: [
1869
- "TODO(open-decision): the escalation transition is a flagged placeholder \u2014 a GET carrying params is not a real request shape (FE doc Screen 11 + open question 7).",
1870
- "The terminal REJECTED variant (failureReason + transitions []) is described in prose, not published as JSON \u2014 no fixture."
1871
- ]
1998
+ notes: ["Only an explicit non-retryable provider or identity-vendor outcome reaches this state."]
1872
1999
  },
1873
2000
  {
1874
2001
  id: "screen-12-pending-order",
@@ -1913,7 +2040,7 @@ var FIXTURES = [
1913
2040
  docRef: "Screen 16 \xB7 Not available",
1914
2041
  screen: 16,
1915
2042
  stateKey: "BLOCKED",
1916
- notes: ["The only flatly terminal state entry in the table."]
2043
+ notes: ["A flatly terminal availability state; explicit non-retryable KYC rejection is terminal too."]
1917
2044
  },
1918
2045
  {
1919
2046
  id: "worked-example-01-quote",
@@ -1945,10 +2072,6 @@ var FIXTURE_COVERAGE_GAPS = [
1945
2072
  {
1946
2073
  stateKey: "FUN_AUTH",
1947
2074
  reason: "No step response exists in either doc \u2014 shape owned by the auth spike, and FUN_AUTH never renders in fomo. TODO(open-decision): contract \xA7Auth & ref binding, item 5."
1948
- },
1949
- {
1950
- stateKey: "KYC/CAPTURE",
1951
- reason: "Dropped from v1 (FE Screen 8 tombstone, no UK module coverage); no step response was ever published. Kind retained as handshake-gated vocabulary."
1952
2075
  }
1953
2076
  ];
1954
2077
  var fixtureMeta = (id) => {