@metamask/ramps-controller 20.2.0 → 20.3.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +14 -1
  2. package/dist/NeoBankService-method-action-types.cjs +7 -0
  3. package/dist/NeoBankService-method-action-types.cjs.map +1 -0
  4. package/dist/NeoBankService-method-action-types.d.cts +126 -0
  5. package/dist/NeoBankService-method-action-types.d.cts.map +1 -0
  6. package/dist/NeoBankService-method-action-types.d.mts +126 -0
  7. package/dist/NeoBankService-method-action-types.d.mts.map +1 -0
  8. package/dist/NeoBankService-method-action-types.mjs +6 -0
  9. package/dist/NeoBankService-method-action-types.mjs.map +1 -0
  10. package/dist/NeoBankService.cjs +387 -0
  11. package/dist/NeoBankService.cjs.map +1 -0
  12. package/dist/NeoBankService.d.cts +191 -0
  13. package/dist/NeoBankService.d.cts.map +1 -0
  14. package/dist/NeoBankService.d.mts +191 -0
  15. package/dist/NeoBankService.d.mts.map +1 -0
  16. package/dist/NeoBankService.mjs +379 -0
  17. package/dist/NeoBankService.mjs.map +1 -0
  18. package/dist/RampsController-method-action-types.cjs.map +1 -1
  19. package/dist/RampsController-method-action-types.d.cts +91 -1
  20. package/dist/RampsController-method-action-types.d.cts.map +1 -1
  21. package/dist/RampsController-method-action-types.d.mts +91 -1
  22. package/dist/RampsController-method-action-types.d.mts.map +1 -1
  23. package/dist/RampsController-method-action-types.mjs.map +1 -1
  24. package/dist/RampsController.cjs +372 -2
  25. package/dist/RampsController.cjs.map +1 -1
  26. package/dist/RampsController.d.cts +152 -5
  27. package/dist/RampsController.d.cts.map +1 -1
  28. package/dist/RampsController.d.mts +152 -5
  29. package/dist/RampsController.d.mts.map +1 -1
  30. package/dist/RampsController.mjs +371 -1
  31. package/dist/RampsController.mjs.map +1 -1
  32. package/dist/autoramp-types.cjs +3 -0
  33. package/dist/autoramp-types.cjs.map +1 -0
  34. package/dist/autoramp-types.d.cts +22 -0
  35. package/dist/autoramp-types.d.cts.map +1 -0
  36. package/dist/autoramp-types.d.mts +22 -0
  37. package/dist/autoramp-types.d.mts.map +1 -0
  38. package/dist/autoramp-types.mjs +2 -0
  39. package/dist/autoramp-types.mjs.map +1 -0
  40. package/dist/autorampAccount.cjs +155 -0
  41. package/dist/autorampAccount.cjs.map +1 -0
  42. package/dist/autorampAccount.d.cts +126 -0
  43. package/dist/autorampAccount.d.cts.map +1 -0
  44. package/dist/autorampAccount.d.mts +126 -0
  45. package/dist/autorampAccount.d.mts.map +1 -0
  46. package/dist/autorampAccount.mjs +147 -0
  47. package/dist/autorampAccount.mjs.map +1 -0
  48. package/dist/index.cjs +20 -1
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +12 -3
  51. package/dist/index.d.cts.map +1 -1
  52. package/dist/index.d.mts +12 -3
  53. package/dist/index.d.mts.map +1 -1
  54. package/dist/index.mjs +5 -1
  55. package/dist/index.mjs.map +1 -1
  56. package/dist/ownership-message.cjs +26 -0
  57. package/dist/ownership-message.cjs.map +1 -0
  58. package/dist/ownership-message.d.cts +22 -0
  59. package/dist/ownership-message.d.cts.map +1 -0
  60. package/dist/ownership-message.d.mts +22 -0
  61. package/dist/ownership-message.d.mts.map +1 -0
  62. package/dist/ownership-message.mjs +22 -0
  63. package/dist/ownership-message.mjs.map +1 -0
  64. package/dist/wallet-registration-machine.cjs +144 -0
  65. package/dist/wallet-registration-machine.cjs.map +1 -0
  66. package/dist/wallet-registration-machine.d.cts +81 -0
  67. package/dist/wallet-registration-machine.d.cts.map +1 -0
  68. package/dist/wallet-registration-machine.d.mts +81 -0
  69. package/dist/wallet-registration-machine.d.mts.map +1 -0
  70. package/dist/wallet-registration-machine.mjs +139 -0
  71. package/dist/wallet-registration-machine.mjs.map +1 -0
  72. package/dist/wallet-registration-service.cjs +351 -0
  73. package/dist/wallet-registration-service.cjs.map +1 -0
  74. package/dist/wallet-registration-service.d.cts +144 -0
  75. package/dist/wallet-registration-service.d.cts.map +1 -0
  76. package/dist/wallet-registration-service.d.mts +144 -0
  77. package/dist/wallet-registration-service.d.mts.map +1 -0
  78. package/dist/wallet-registration-service.mjs +344 -0
  79. package/dist/wallet-registration-service.mjs.map +1 -0
  80. package/package.json +3 -3
@@ -9,16 +9,20 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
11
  };
12
- var _RampsController_instances, _RampsController_requestCacheTTL, _RampsController_requestCacheMaxSize, _RampsController_pendingRequests, _RampsController_pendingResourceCount, _RampsController_pendingResourceGeneration, _RampsController_orderPollingMeta, _RampsController_orderPollingTimer, _RampsController_isPolling, _RampsController_initPromise, _RampsController_clearPendingResourceCountForDependentResources, _RampsController_abortDependentRequests, _RampsController_resolveAllProvidersFlag, _RampsController_mutateRequests, _RampsController_removeRequestState, _RampsController_cleanupState, _RampsController_requireRegion, _RampsController_isRegionCurrent, _RampsController_isTokenCurrent, _RampsController_isProviderCurrent, _RampsController_updateResourceField, _RampsController_setResourceLoading, _RampsController_setResourceError, _RampsController_updateRequestState, _RampsController_runInit, _RampsController_syncUserRegionFromCountriesCatalog, _RampsController_pickWidenedQuote, _RampsController_getSupportingProvidersForRegion, _RampsController_filterProviderIdsBySupport, _RampsController_resolveProviderIdsForQuote, _RampsController_resolveProviderIdsForPaymentMethods, _RampsController_getPreferredProviderIdsFromOrders, _RampsController_refreshOrder, _RampsController_pollPendingOrders, _RampsController_syncTransakAuthOnError, _RampsController_getNormalizedTransakError;
12
+ var _RampsController_instances, _RampsController_requestCacheTTL, _RampsController_requestCacheMaxSize, _RampsController_pendingRequests, _RampsController_pendingResourceCount, _RampsController_pendingResourceGeneration, _RampsController_orderPollingMeta, _RampsController_orderPollingTimer, _RampsController_isPolling, _RampsController_initPromise, _RampsController_clearPendingResourceCountForDependentResources, _RampsController_abortDependentRequests, _RampsController_resolveAllProvidersFlag, _RampsController_mutateRequests, _RampsController_removeRequestState, _RampsController_cleanupState, _RampsController_requireRegion, _RampsController_isRegionCurrent, _RampsController_isTokenCurrent, _RampsController_isProviderCurrent, _RampsController_updateResourceField, _RampsController_setResourceLoading, _RampsController_setResourceError, _RampsController_updateRequestState, _RampsController_runInit, _RampsController_syncUserRegionFromCountriesCatalog, _RampsController_pickWidenedQuote, _RampsController_getSupportingProvidersForRegion, _RampsController_filterProviderIdsBySupport, _RampsController_resolveProviderIdsForQuote, _RampsController_resolveProviderIdsForPaymentMethods, _RampsController_getPreferredProviderIdsFromOrders, _RampsController_applyAutorampRemoteSnapshot, _RampsController_refreshOrder, _RampsController_pollPendingOrders, _RampsController_syncTransakAuthOnError, _RampsController_getNormalizedTransakError;
13
13
  import { BaseController } from "@metamask/base-controller";
14
14
  import { BrokenCircuitError } from "@metamask/controller-utils";
15
+ import { applyAutorampRemoteStatus, createAutorampAccount, markAutorampNotified } from "./autorampAccount.mjs";
15
16
  import { getHeadlessProviderAllowlist, isHeadlessAllProvidersEnabled, normalizeHeadlessProviderId } from "./featureFlags.mjs";
16
17
  import { PENDING_ORDER_STATUSES, TERMINAL_ORDER_STATUSES } from "./orderStatus.mjs";
18
+ import { buildOwnershipMessage } from "./ownership-message.mjs";
17
19
  import { mergePaymentMethodsById, pickPaymentMethod } from "./paymentMethodMerge.mjs";
18
20
  import { getProvidersServingAsset, normalizeRampsAssetId, providerServesAsset } from "./providerAvailability.mjs";
19
21
  import { RAMPS_ERROR_CODES } from "./rampsErrorCodes.mjs";
20
22
  import { RampsOrderStatus } from "./RampsService.mjs";
21
23
  import { DEFAULT_REQUEST_CACHE_TTL, DEFAULT_REQUEST_CACHE_MAX_SIZE, createCacheKey, isCacheExpired, createLoadingState, createSuccessState, createErrorState, RequestStatus } from "./RequestCache.mjs";
24
+ import { createInitialState as createInitialWalletRegistrationState, transition as transitionWalletRegistration } from "./wallet-registration-machine.mjs";
25
+ import { createIdempotencyKey, WalletRegistrationError } from "./wallet-registration-service.mjs";
22
26
  // === GENERAL ===
23
27
  /**
24
28
  * The name of the {@link RampsController}, used to namespace the
@@ -67,7 +71,36 @@ export const RAMPS_CONTROLLER_REQUIRED_SERVICE_ACTIONS = [
67
71
  'TransakService:cancelOrder',
68
72
  'TransakService:cancelAllActiveOrders',
69
73
  'TransakService:getActiveOrders',
74
+ 'NeoBankService:getAutoramp',
75
+ 'NeoBankService:createAutoramp',
76
+ 'NeoBankService:getCustomerByExternalId',
77
+ 'NeoBankService:getWalletRegistrationStatus',
78
+ 'NeoBankService:registerSelfHostedWallet',
70
79
  ];
80
+ /**
81
+ * Every external controller action RampsController calls via the messenger,
82
+ * which hosts must delegate from the root messenger.
83
+ * `AuthenticationController:getSessionProfile` resolves the vendor customer
84
+ * identity from Profile Sync, and `KeyringController:signPersonalMessage` signs
85
+ * the EIP-191 ownership proof for Money Account self-hosted wallet
86
+ * registration; both are only exercised by the autoramp paths.
87
+ */
88
+ export const RAMPS_CONTROLLER_REQUIRED_CONTROLLER_ACTIONS = [
89
+ 'AuthenticationController:getSessionProfile',
90
+ 'KeyringController:signPersonalMessage',
91
+ 'RemoteFeatureFlagController:getState',
92
+ ];
93
+ /**
94
+ * Distinguishes an already-materialized {@link AutorampAccount} from the
95
+ * create-fields shape accepted by {@link RampsController.addAutoramp}.
96
+ *
97
+ * @param value - Full account or create fields.
98
+ * @returns Whether the value already carries the derived account fields.
99
+ */
100
+ function isFullAutorampAccount(value) {
101
+ return (typeof value.updatedAt === 'number' &&
102
+ value.lastSeenStatus !== undefined);
103
+ }
71
104
  /**
72
105
  * Default TTL for quotes requests (15 seconds).
73
106
  * Quotes are time-sensitive and should have a shorter cache duration.
@@ -179,6 +212,12 @@ const rampsControllerMetadata = {
179
212
  includeInStateLogs: true,
180
213
  usedInUi: true,
181
214
  },
215
+ autoramps: {
216
+ persist: true,
217
+ includeInDebugSnapshot: true,
218
+ includeInStateLogs: true,
219
+ usedInUi: true,
220
+ },
182
221
  providerAutoSelected: {
183
222
  persist: true,
184
223
  includeInDebugSnapshot: true,
@@ -228,6 +267,7 @@ export function getDefaultRampsControllerState() {
228
267
  },
229
268
  },
230
269
  orders: [],
270
+ autoramps: [],
231
271
  providerAutoSelected: false,
232
272
  };
233
273
  }
@@ -373,6 +413,14 @@ const MESSENGER_EXPOSED_METHODS = [
373
413
  'getQuotes',
374
414
  'addOrder',
375
415
  'removeOrder',
416
+ 'addAutoramp',
417
+ 'createAutoramp',
418
+ 'removeAutoramp',
419
+ 'registerMoneyAccountWallet',
420
+ 'markAutorampAsNotified',
421
+ 'applyAutorampStatusFromPush',
422
+ 'refreshAutoramp',
423
+ 'refreshAutoramps',
376
424
  'startOrderPolling',
377
425
  'stopOrderPolling',
378
426
  'getBuyWidgetData',
@@ -1378,6 +1426,304 @@ export class RampsController extends BaseController {
1378
1426
  });
1379
1427
  __classPrivateFieldGet(this, _RampsController_orderPollingMeta, "f").delete(providerOrderId);
1380
1428
  }
1429
+ /**
1430
+ * Adds or updates a local autoramp last-seen cursor (e.g. after create).
1431
+ *
1432
+ * @param accountOrInput - Full account or create fields.
1433
+ * @returns The upserted {@link AutorampAccount}.
1434
+ */
1435
+ addAutoramp(accountOrInput) {
1436
+ const account = isFullAutorampAccount(accountOrInput)
1437
+ ? accountOrInput
1438
+ : createAutorampAccount(accountOrInput);
1439
+ this.update((state) => {
1440
+ const idx = state.autoramps.findIndex((existing) => existing.id === account.id);
1441
+ if (idx === -1) {
1442
+ state.autoramps.push(account);
1443
+ }
1444
+ else {
1445
+ state.autoramps[idx] = {
1446
+ ...state.autoramps[idx],
1447
+ ...account,
1448
+ };
1449
+ }
1450
+ });
1451
+ return (this.state.autoramps.find((existing) => existing.id === account.id) ??
1452
+ account);
1453
+ }
1454
+ /**
1455
+ * Creates an autoramp via the neo-bank proxy and applies the returned
1456
+ * snapshot as the local last-seen cursor.
1457
+ *
1458
+ * The vendor `customer_id` is resolved via
1459
+ * {@link RampsController.resolveAutorampCustomerId} and injected into the
1460
+ * request (any caller-supplied `customer_id` is overwritten).
1461
+ *
1462
+ * @param request - CreateAutoramp payload.
1463
+ * @param options - Optional idempotency key forwarded to the proxy.
1464
+ * @param options.idempotencyKey - Value sent as `Idempotency-Key`.
1465
+ * @returns The created/updated local {@link AutorampAccount}.
1466
+ */
1467
+ async createAutoramp(request, options = {}) {
1468
+ const customerId = await this.resolveAutorampCustomerId();
1469
+ const body = { ...request, customer_id: customerId };
1470
+ const remote = await this.messenger.call('NeoBankService:createAutoramp', body, options);
1471
+ return __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_applyAutorampRemoteSnapshot).call(this, remote);
1472
+ }
1473
+ /**
1474
+ * Resolves the vendor `customer_id` for autoramp / Money Account operations.
1475
+ *
1476
+ * Maps the wallet's Profile Sync id (the partner `external_id`) to the
1477
+ * vendor customer via `GET /neobank/customers/{external_id}/external`.
1478
+ *
1479
+ * @returns The vendor customer id.
1480
+ */
1481
+ async resolveAutorampCustomerId() {
1482
+ const profile = await this.messenger.call('AuthenticationController:getSessionProfile');
1483
+ const canonical = profile?.canonicalProfileId;
1484
+ const externalId = typeof canonical === 'string' && canonical.length > 0
1485
+ ? canonical
1486
+ : profile?.profileId;
1487
+ if (typeof externalId !== 'string' || externalId.length === 0) {
1488
+ throw new Error('Cannot resolve MoonPay customer id: wallet is not signed in to Profile Sync.');
1489
+ }
1490
+ const customer = await this.messenger.call('NeoBankService:getCustomerByExternalId', externalId);
1491
+ const customerId = customer &&
1492
+ typeof customer === 'object' &&
1493
+ typeof customer.id === 'string'
1494
+ ? customer.id
1495
+ : null;
1496
+ if (!customerId) {
1497
+ throw new Error(`Cannot resolve MoonPay customer id: no MoonPay customer is mapped to external id "${externalId}".`);
1498
+ }
1499
+ return customerId;
1500
+ }
1501
+ /**
1502
+ * Registers a Money Account wallet with MoonPay Iron via neobank-proxy.
1503
+ *
1504
+ * @param params - Money Account wallet registration parameters.
1505
+ * @param params.address - Monad Money Account address.
1506
+ * @returns The registration state, or `{ type: 'lookupUnavailable' }` when
1507
+ * the address-list lookup fails (never treated as unregistered).
1508
+ */
1509
+ async registerMoneyAccountWallet({ address, }) {
1510
+ let machine = transitionWalletRegistration(createInitialWalletRegistrationState(), { type: 'START' });
1511
+ const toExistingResult = (status) => {
1512
+ if (status.type === 'active') {
1513
+ return { type: 'alreadyRegistered', registration: status.registration };
1514
+ }
1515
+ if (status.type === 'disabled') {
1516
+ return {
1517
+ type: 'registeredDisabled',
1518
+ registration: status.registration,
1519
+ };
1520
+ }
1521
+ return undefined;
1522
+ };
1523
+ const customerId = await this.resolveAutorampCustomerId();
1524
+ const toLookupUnavailableResult = (error) => {
1525
+ machine = transitionWalletRegistration(machine, {
1526
+ type: 'LOOKUP_FAILED',
1527
+ });
1528
+ return {
1529
+ type: 'lookupUnavailable',
1530
+ error: error instanceof WalletRegistrationError
1531
+ ? error
1532
+ : new WalletRegistrationError('lookupUnavailable', {
1533
+ message: 'self-hosted address lookup failed',
1534
+ body: error instanceof Error ? error.message : undefined,
1535
+ }),
1536
+ };
1537
+ };
1538
+ const lookup = async () => {
1539
+ try {
1540
+ return await this.messenger.call('NeoBankService:getWalletRegistrationStatus', { customerId, address });
1541
+ }
1542
+ catch (error) {
1543
+ return toLookupUnavailableResult(error);
1544
+ }
1545
+ };
1546
+ const applyLookup = (status) => {
1547
+ let eventType = 'LOOKUP_ABSENT';
1548
+ if (status.type === 'active') {
1549
+ eventType = 'LOOKUP_ACTIVE';
1550
+ }
1551
+ else if (status.type === 'disabled') {
1552
+ eventType = 'LOOKUP_DISABLED';
1553
+ }
1554
+ machine = transitionWalletRegistration(machine, {
1555
+ type: eventType,
1556
+ });
1557
+ return toExistingResult(status);
1558
+ };
1559
+ const resolveLookup = async () => {
1560
+ const status = await lookup();
1561
+ if (status.type === 'lookupUnavailable') {
1562
+ return status;
1563
+ }
1564
+ return applyLookup(status);
1565
+ };
1566
+ const existingResult = await resolveLookup();
1567
+ if (existingResult) {
1568
+ return existingResult;
1569
+ }
1570
+ let idempotencyKey = createIdempotencyKey();
1571
+ let lastMessage;
1572
+ while (true) {
1573
+ const message = buildOwnershipMessage({
1574
+ address,
1575
+ customerId,
1576
+ now: new Date(),
1577
+ });
1578
+ if (lastMessage !== undefined && message !== lastMessage) {
1579
+ idempotencyKey = createIdempotencyKey();
1580
+ }
1581
+ lastMessage = message;
1582
+ let signature;
1583
+ try {
1584
+ signature = await this.messenger.call('KeyringController:signPersonalMessage', { data: message, from: address });
1585
+ machine = transitionWalletRegistration(machine, { type: 'SIGN_OK' });
1586
+ }
1587
+ catch (error) {
1588
+ machine = transitionWalletRegistration(machine, {
1589
+ type: 'SIGN_FAILED',
1590
+ retryable: false,
1591
+ });
1592
+ throw error;
1593
+ }
1594
+ try {
1595
+ const result = await this.messenger.call('NeoBankService:registerSelfHostedWallet', {
1596
+ address,
1597
+ customerId,
1598
+ message,
1599
+ signature,
1600
+ idempotencyKey,
1601
+ });
1602
+ machine = transitionWalletRegistration(machine, { type: 'SUBMIT_OK' });
1603
+ return result;
1604
+ }
1605
+ catch (error) {
1606
+ if (!(error instanceof WalletRegistrationError)) {
1607
+ machine = transitionWalletRegistration(machine, {
1608
+ type: 'SUBMIT_TERMINAL',
1609
+ });
1610
+ throw error;
1611
+ }
1612
+ if (error.kind === 'conflict') {
1613
+ machine = transitionWalletRegistration(machine, {
1614
+ type: 'SUBMIT_CONFLICT',
1615
+ });
1616
+ }
1617
+ else if (error.kind === 'transient') {
1618
+ machine = transitionWalletRegistration(machine, {
1619
+ type: 'SUBMIT_TRANSIENT',
1620
+ });
1621
+ }
1622
+ else if (error.kind === 'validation') {
1623
+ machine = transitionWalletRegistration(machine, {
1624
+ type: 'SUBMIT_VALIDATION',
1625
+ utcRollover: buildOwnershipMessage({
1626
+ address,
1627
+ customerId,
1628
+ now: new Date(),
1629
+ }) !== message,
1630
+ });
1631
+ }
1632
+ else if (error.kind === 'rateLimited') {
1633
+ machine = transitionWalletRegistration(machine, {
1634
+ type: 'SUBMIT_RATE_LIMITED',
1635
+ });
1636
+ }
1637
+ else {
1638
+ machine = transitionWalletRegistration(machine, {
1639
+ type: 'SUBMIT_TERMINAL',
1640
+ });
1641
+ }
1642
+ if (machine.status === 'disambiguate409' ||
1643
+ machine.status === 'checkThenRetry') {
1644
+ const reconciledResult = await resolveLookup();
1645
+ if (reconciledResult) {
1646
+ return reconciledResult;
1647
+ }
1648
+ }
1649
+ if (machine.status !== 'signing') {
1650
+ throw error;
1651
+ }
1652
+ }
1653
+ }
1654
+ }
1655
+ /**
1656
+ * Removes a local autoramp last-seen cursor by id.
1657
+ *
1658
+ * @param autorampId - MoonPay autoramp id.
1659
+ */
1660
+ removeAutoramp(autorampId) {
1661
+ this.update((state) => {
1662
+ state.autoramps = state.autoramps.filter((autoramp) => autoramp.id !== autorampId);
1663
+ });
1664
+ }
1665
+ /**
1666
+ * Marks that the UI has already notified for the autoramp's current status.
1667
+ *
1668
+ * @param autorampId - MoonPay autoramp id.
1669
+ */
1670
+ markAutorampAsNotified(autorampId) {
1671
+ const existing = this.state.autoramps.find((autoramp) => autoramp.id === autorampId);
1672
+ if (!existing) {
1673
+ return;
1674
+ }
1675
+ const notified = markAutorampNotified(existing);
1676
+ this.update((state) => {
1677
+ const idx = state.autoramps.findIndex((autoramp) => autoramp.id === autorampId);
1678
+ if (idx !== -1) {
1679
+ state.autoramps[idx] = notified;
1680
+ }
1681
+ });
1682
+ }
1683
+ /**
1684
+ * Applies a remote autoramp snapshot from a websocket / webhook push.
1685
+ *
1686
+ * @param remote - Remote autoramp snapshot.
1687
+ * @returns The updated local account.
1688
+ */
1689
+ applyAutorampStatusFromPush(remote) {
1690
+ return __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_applyAutorampRemoteSnapshot).call(this, remote);
1691
+ }
1692
+ /**
1693
+ * Fetches one autoramp from the neo-bank proxy and applies it to the
1694
+ * last-seen cursor. Does not recreate a cursor that was removed while the
1695
+ * request was in flight.
1696
+ *
1697
+ * @param autorampId - MoonPay autoramp id.
1698
+ * @returns The updated local account, or an unpersisted snapshot if the
1699
+ * cursor was removed during the fetch.
1700
+ */
1701
+ async refreshAutoramp(autorampId) {
1702
+ const remote = await this.messenger.call('NeoBankService:getAutoramp', autorampId);
1703
+ return __classPrivateFieldGet(this, _RampsController_instances, "m", _RampsController_applyAutorampRemoteSnapshot).call(this, remote, { allowInsert: false });
1704
+ }
1705
+ /**
1706
+ * Refreshes all known local autoramps from MoonPay.
1707
+ * Intended for app resume / unlock catch-up when webhooks were missed.
1708
+ *
1709
+ * @returns Updated autoramp accounts (failed fetches are skipped).
1710
+ */
1711
+ async refreshAutoramps() {
1712
+ const ids = this.state.autoramps.map((autoramp) => autoramp.id);
1713
+ const updated = [];
1714
+ for (const id of ids) {
1715
+ try {
1716
+ const account = await this.refreshAutoramp(id);
1717
+ if (this.state.autoramps.some((autoramp) => autoramp.id === account.id)) {
1718
+ updated.push(account);
1719
+ }
1720
+ }
1721
+ catch {
1722
+ // Keep local cursor for this id; continue remaining refreshes.
1723
+ }
1724
+ }
1725
+ return updated;
1726
+ }
1381
1727
  /**
1382
1728
  * Starts polling all pending V2 orders at a fixed interval.
1383
1729
  * Each poll cycle iterates orders with non-terminal statuses,
@@ -2336,6 +2682,30 @@ async function _RampsController_resolveProviderIdsForPaymentMethods({ assetId, r
2336
2682
  }
2337
2683
  }
2338
2684
  return orderedIds;
2685
+ }, _RampsController_applyAutorampRemoteSnapshot = function _RampsController_applyAutorampRemoteSnapshot(remote, { allowInsert = true } = {}) {
2686
+ const local = this.state.autoramps.find((autoramp) => autoramp.id === remote.id) ??
2687
+ null;
2688
+ if (local === null && !allowInsert) {
2689
+ return applyAutorampRemoteStatus(null, remote).account;
2690
+ }
2691
+ const result = applyAutorampRemoteStatus(local, remote);
2692
+ this.update((state) => {
2693
+ const idx = state.autoramps.findIndex((autoramp) => autoramp.id === result.account.id);
2694
+ if (idx === -1) {
2695
+ state.autoramps.push(result.account);
2696
+ }
2697
+ else {
2698
+ state.autoramps[idx] = result.account;
2699
+ }
2700
+ });
2701
+ if (result.statusChanged) {
2702
+ this.messenger.publish('RampsController:autorampStatusChanged', {
2703
+ autoramp: result.account,
2704
+ previousStatus: result.previousStatus,
2705
+ shouldNotify: result.shouldNotify,
2706
+ });
2707
+ }
2708
+ return (this.state.autoramps.find((autoramp) => autoramp.id === result.account.id) ?? result.account);
2339
2709
  }, _RampsController_refreshOrder =
2340
2710
  /**
2341
2711
  * Refreshes a single order via the V2 API and updates it in state.