@metamask-previews/perps-controller 0.0.0-preview-685dbf46b → 1.0.0-preview-bc00f2c
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/CHANGELOG.md +30 -2
- package/dist/PerpsController.cjs +3077 -65
- package/dist/PerpsController.cjs.map +1 -1
- package/dist/PerpsController.d.cts +969 -82
- package/dist/PerpsController.d.cts.map +1 -1
- package/dist/PerpsController.d.mts +969 -82
- package/dist/PerpsController.d.mts.map +1 -1
- package/dist/PerpsController.mjs +3073 -62
- package/dist/PerpsController.mjs.map +1 -1
- package/dist/aggregation/SubscriptionMultiplexer.cjs +441 -0
- package/dist/aggregation/SubscriptionMultiplexer.cjs.map +1 -0
- package/dist/aggregation/SubscriptionMultiplexer.d.cts +171 -0
- package/dist/aggregation/SubscriptionMultiplexer.d.cts.map +1 -0
- package/dist/aggregation/SubscriptionMultiplexer.d.mts +171 -0
- package/dist/aggregation/SubscriptionMultiplexer.d.mts.map +1 -0
- package/dist/aggregation/SubscriptionMultiplexer.mjs +437 -0
- package/dist/aggregation/SubscriptionMultiplexer.mjs.map +1 -0
- package/dist/aggregation/index.cjs +9 -0
- package/dist/aggregation/index.cjs.map +1 -0
- package/dist/aggregation/index.d.cts +6 -0
- package/dist/aggregation/index.d.cts.map +1 -0
- package/dist/aggregation/index.d.mts +6 -0
- package/dist/aggregation/index.d.mts.map +1 -0
- package/dist/aggregation/index.mjs +5 -0
- package/dist/aggregation/index.mjs.map +1 -0
- package/dist/constants/chartConfig.cjs +227 -0
- package/dist/constants/chartConfig.cjs.map +1 -0
- package/dist/constants/chartConfig.d.cts +216 -0
- package/dist/constants/chartConfig.d.cts.map +1 -0
- package/dist/constants/chartConfig.d.mts +216 -0
- package/dist/constants/chartConfig.d.mts.map +1 -0
- package/dist/constants/chartConfig.mjs +221 -0
- package/dist/constants/chartConfig.mjs.map +1 -0
- package/dist/constants/eventNames.cjs +436 -0
- package/dist/constants/eventNames.cjs.map +1 -0
- package/dist/constants/eventNames.d.cts +387 -0
- package/dist/constants/eventNames.d.cts.map +1 -0
- package/dist/constants/eventNames.d.mts +387 -0
- package/dist/constants/eventNames.d.mts.map +1 -0
- package/dist/constants/eventNames.mjs +433 -0
- package/dist/constants/eventNames.mjs.map +1 -0
- package/dist/constants/hyperLiquidConfig.cjs +380 -0
- package/dist/constants/hyperLiquidConfig.cjs.map +1 -0
- package/dist/constants/hyperLiquidConfig.d.cts +236 -0
- package/dist/constants/hyperLiquidConfig.d.cts.map +1 -0
- package/dist/constants/hyperLiquidConfig.d.mts +236 -0
- package/dist/constants/hyperLiquidConfig.d.mts.map +1 -0
- package/dist/constants/hyperLiquidConfig.mjs +371 -0
- package/dist/constants/hyperLiquidConfig.mjs.map +1 -0
- package/dist/constants/index.cjs +28 -0
- package/dist/constants/index.cjs.map +1 -0
- package/dist/constants/index.d.cts +12 -0
- package/dist/constants/index.d.cts.map +1 -0
- package/dist/constants/index.d.mts +12 -0
- package/dist/constants/index.d.mts.map +1 -0
- package/dist/constants/index.mjs +12 -0
- package/dist/constants/index.mjs.map +1 -0
- package/dist/constants/myxConfig.cjs +229 -0
- package/dist/constants/myxConfig.cjs.map +1 -0
- package/dist/constants/myxConfig.d.cts +106 -0
- package/dist/constants/myxConfig.d.cts.map +1 -0
- package/dist/constants/myxConfig.d.mts +106 -0
- package/dist/constants/myxConfig.d.mts.map +1 -0
- package/dist/constants/myxConfig.mjs +219 -0
- package/dist/constants/myxConfig.mjs.map +1 -0
- package/dist/constants/orderTypes.cjs +31 -0
- package/dist/constants/orderTypes.cjs.map +1 -0
- package/dist/constants/orderTypes.d.cts +19 -0
- package/dist/constants/orderTypes.d.cts.map +1 -0
- package/dist/constants/orderTypes.d.mts +19 -0
- package/dist/constants/orderTypes.d.mts.map +1 -0
- package/dist/constants/orderTypes.mjs +27 -0
- package/dist/constants/orderTypes.mjs.map +1 -0
- package/dist/constants/performanceMetrics.cjs +63 -0
- package/dist/constants/performanceMetrics.cjs.map +1 -0
- package/dist/constants/performanceMetrics.d.cts +46 -0
- package/dist/constants/performanceMetrics.d.cts.map +1 -0
- package/dist/constants/performanceMetrics.d.mts +46 -0
- package/dist/constants/performanceMetrics.d.mts.map +1 -0
- package/dist/constants/performanceMetrics.mjs +60 -0
- package/dist/constants/performanceMetrics.mjs.map +1 -0
- package/dist/constants/perpsConfig.cjs +295 -0
- package/dist/constants/perpsConfig.cjs.map +1 -0
- package/dist/constants/perpsConfig.d.cts +221 -0
- package/dist/constants/perpsConfig.d.cts.map +1 -0
- package/dist/constants/perpsConfig.d.mts +221 -0
- package/dist/constants/perpsConfig.d.mts.map +1 -0
- package/dist/constants/perpsConfig.mjs +292 -0
- package/dist/constants/perpsConfig.mjs.map +1 -0
- package/dist/constants/transactionsHistoryConfig.cjs +19 -0
- package/dist/constants/transactionsHistoryConfig.cjs.map +1 -0
- package/dist/constants/transactionsHistoryConfig.d.cts +16 -0
- package/dist/constants/transactionsHistoryConfig.d.cts.map +1 -0
- package/dist/constants/transactionsHistoryConfig.d.mts +16 -0
- package/dist/constants/transactionsHistoryConfig.d.mts.map +1 -0
- package/dist/constants/transactionsHistoryConfig.mjs +16 -0
- package/dist/constants/transactionsHistoryConfig.mjs.map +1 -0
- package/dist/index.cjs +63 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +38 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +46 -1
- package/dist/index.mjs.map +1 -1
- package/dist/perpsErrorCodes.cjs +80 -0
- package/dist/perpsErrorCodes.cjs.map +1 -0
- package/dist/perpsErrorCodes.d.cts +65 -0
- package/dist/perpsErrorCodes.d.cts.map +1 -0
- package/dist/perpsErrorCodes.d.mts +65 -0
- package/dist/perpsErrorCodes.d.mts.map +1 -0
- package/dist/perpsErrorCodes.mjs +77 -0
- package/dist/perpsErrorCodes.mjs.map +1 -0
- package/dist/providers/AggregatedPerpsProvider.cjs +508 -0
- package/dist/providers/AggregatedPerpsProvider.cjs.map +1 -0
- package/dist/providers/AggregatedPerpsProvider.d.cts +171 -0
- package/dist/providers/AggregatedPerpsProvider.d.cts.map +1 -0
- package/dist/providers/AggregatedPerpsProvider.d.mts +171 -0
- package/dist/providers/AggregatedPerpsProvider.d.mts.map +1 -0
- package/dist/providers/AggregatedPerpsProvider.mjs +504 -0
- package/dist/providers/AggregatedPerpsProvider.mjs.map +1 -0
- package/dist/providers/HyperLiquidProvider.cjs +5679 -0
- package/dist/providers/HyperLiquidProvider.cjs.map +1 -0
- package/dist/providers/HyperLiquidProvider.d.cts +516 -0
- package/dist/providers/HyperLiquidProvider.d.cts.map +1 -0
- package/dist/providers/HyperLiquidProvider.d.mts +516 -0
- package/dist/providers/HyperLiquidProvider.d.mts.map +1 -0
- package/dist/providers/HyperLiquidProvider.mjs +5675 -0
- package/dist/providers/HyperLiquidProvider.mjs.map +1 -0
- package/dist/providers/MYXProvider.cjs +514 -0
- package/dist/providers/MYXProvider.cjs.map +1 -0
- package/dist/providers/MYXProvider.d.cts +105 -0
- package/dist/providers/MYXProvider.d.cts.map +1 -0
- package/dist/providers/MYXProvider.d.mts +105 -0
- package/dist/providers/MYXProvider.d.mts.map +1 -0
- package/dist/providers/MYXProvider.mjs +510 -0
- package/dist/providers/MYXProvider.mjs.map +1 -0
- package/dist/routing/ProviderRouter.cjs +154 -0
- package/dist/routing/ProviderRouter.cjs.map +1 -0
- package/dist/routing/ProviderRouter.d.cts +112 -0
- package/dist/routing/ProviderRouter.d.cts.map +1 -0
- package/dist/routing/ProviderRouter.d.mts +112 -0
- package/dist/routing/ProviderRouter.d.mts.map +1 -0
- package/dist/routing/ProviderRouter.mjs +150 -0
- package/dist/routing/ProviderRouter.mjs.map +1 -0
- package/dist/routing/index.cjs +9 -0
- package/dist/routing/index.cjs.map +1 -0
- package/dist/routing/index.d.cts +6 -0
- package/dist/routing/index.d.cts.map +1 -0
- package/dist/routing/index.d.mts +6 -0
- package/dist/routing/index.d.mts.map +1 -0
- package/dist/routing/index.mjs +5 -0
- package/dist/routing/index.mjs.map +1 -0
- package/dist/selectors.cjs +166 -0
- package/dist/selectors.cjs.map +1 -0
- package/dist/selectors.d.cts +362 -0
- package/dist/selectors.d.cts.map +1 -0
- package/dist/selectors.d.mts +362 -0
- package/dist/selectors.d.mts.map +1 -0
- package/dist/selectors.mjs +158 -0
- package/dist/selectors.mjs.map +1 -0
- package/dist/services/AccountService.cjs +324 -0
- package/dist/services/AccountService.cjs.map +1 -0
- package/dist/services/AccountService.d.cts +56 -0
- package/dist/services/AccountService.d.cts.map +1 -0
- package/dist/services/AccountService.d.mts +56 -0
- package/dist/services/AccountService.d.mts.map +1 -0
- package/dist/services/AccountService.mjs +320 -0
- package/dist/services/AccountService.mjs.map +1 -0
- package/dist/services/DataLakeService.cjs +233 -0
- package/dist/services/DataLakeService.cjs.map +1 -0
- package/dist/services/DataLakeService.d.cts +51 -0
- package/dist/services/DataLakeService.d.cts.map +1 -0
- package/dist/services/DataLakeService.d.mts +51 -0
- package/dist/services/DataLakeService.d.mts.map +1 -0
- package/dist/services/DataLakeService.mjs +229 -0
- package/dist/services/DataLakeService.mjs.map +1 -0
- package/dist/services/DepositService.cjs +98 -0
- package/dist/services/DepositService.cjs.map +1 -0
- package/dist/services/DepositService.d.cts +39 -0
- package/dist/services/DepositService.d.cts.map +1 -0
- package/dist/services/DepositService.d.mts +39 -0
- package/dist/services/DepositService.d.mts.map +1 -0
- package/dist/services/DepositService.mjs +94 -0
- package/dist/services/DepositService.mjs.map +1 -0
- package/dist/services/EligibilityService.cjs +173 -0
- package/dist/services/EligibilityService.cjs.map +1 -0
- package/dist/services/EligibilityService.d.cts +39 -0
- package/dist/services/EligibilityService.d.cts.map +1 -0
- package/dist/services/EligibilityService.d.mts +39 -0
- package/dist/services/EligibilityService.d.mts.map +1 -0
- package/dist/services/EligibilityService.mjs +169 -0
- package/dist/services/EligibilityService.mjs.map +1 -0
- package/dist/services/FeatureFlagConfigurationService.cjs +257 -0
- package/dist/services/FeatureFlagConfigurationService.cjs.map +1 -0
- package/dist/services/FeatureFlagConfigurationService.d.cts +73 -0
- package/dist/services/FeatureFlagConfigurationService.d.cts.map +1 -0
- package/dist/services/FeatureFlagConfigurationService.d.mts +73 -0
- package/dist/services/FeatureFlagConfigurationService.d.mts.map +1 -0
- package/dist/services/FeatureFlagConfigurationService.mjs +253 -0
- package/dist/services/FeatureFlagConfigurationService.mjs.map +1 -0
- package/dist/services/HyperLiquidClientService.cjs +867 -0
- package/dist/services/HyperLiquidClientService.cjs.map +1 -0
- package/dist/services/HyperLiquidClientService.d.cts +214 -0
- package/dist/services/HyperLiquidClientService.d.cts.map +1 -0
- package/dist/services/HyperLiquidClientService.d.mts +214 -0
- package/dist/services/HyperLiquidClientService.d.mts.map +1 -0
- package/dist/services/HyperLiquidClientService.mjs +862 -0
- package/dist/services/HyperLiquidClientService.mjs.map +1 -0
- package/dist/services/HyperLiquidSubscriptionService.cjs +2199 -0
- package/dist/services/HyperLiquidSubscriptionService.cjs.map +1 -0
- package/dist/services/HyperLiquidSubscriptionService.d.cts +187 -0
- package/dist/services/HyperLiquidSubscriptionService.d.cts.map +1 -0
- package/dist/services/HyperLiquidSubscriptionService.d.mts +187 -0
- package/dist/services/HyperLiquidSubscriptionService.d.mts.map +1 -0
- package/dist/services/HyperLiquidSubscriptionService.mjs +2195 -0
- package/dist/services/HyperLiquidSubscriptionService.mjs.map +1 -0
- package/dist/services/HyperLiquidWalletService.cjs +163 -0
- package/dist/services/HyperLiquidWalletService.cjs.map +1 -0
- package/dist/services/HyperLiquidWalletService.d.cts +78 -0
- package/dist/services/HyperLiquidWalletService.d.cts.map +1 -0
- package/dist/services/HyperLiquidWalletService.d.mts +78 -0
- package/dist/services/HyperLiquidWalletService.d.mts.map +1 -0
- package/dist/services/HyperLiquidWalletService.mjs +159 -0
- package/dist/services/HyperLiquidWalletService.mjs.map +1 -0
- package/dist/services/MYXClientService.cjs +304 -0
- package/dist/services/MYXClientService.cjs.map +1 -0
- package/dist/services/MYXClientService.d.cts +81 -0
- package/dist/services/MYXClientService.d.cts.map +1 -0
- package/dist/services/MYXClientService.d.mts +81 -0
- package/dist/services/MYXClientService.d.mts.map +1 -0
- package/dist/services/MYXClientService.mjs +300 -0
- package/dist/services/MYXClientService.mjs.map +1 -0
- package/dist/services/MarketDataService.cjs +848 -0
- package/dist/services/MarketDataService.cjs.map +1 -0
- package/dist/services/MarketDataService.d.cts +291 -0
- package/dist/services/MarketDataService.d.cts.map +1 -0
- package/dist/services/MarketDataService.d.mts +291 -0
- package/dist/services/MarketDataService.d.mts.map +1 -0
- package/dist/services/MarketDataService.mjs +844 -0
- package/dist/services/MarketDataService.mjs.map +1 -0
- package/dist/services/RewardsIntegrationService.cjs +120 -0
- package/dist/services/RewardsIntegrationService.cjs.map +1 -0
- package/dist/services/RewardsIntegrationService.d.cts +28 -0
- package/dist/services/RewardsIntegrationService.d.cts.map +1 -0
- package/dist/services/RewardsIntegrationService.d.mts +28 -0
- package/dist/services/RewardsIntegrationService.d.mts.map +1 -0
- package/dist/services/RewardsIntegrationService.mjs +116 -0
- package/dist/services/RewardsIntegrationService.mjs.map +1 -0
- package/dist/services/ServiceContext.cjs +3 -0
- package/dist/services/ServiceContext.cjs.map +1 -0
- package/dist/services/ServiceContext.d.cts +86 -0
- package/dist/services/ServiceContext.d.cts.map +1 -0
- package/dist/services/ServiceContext.d.mts +86 -0
- package/dist/services/ServiceContext.d.mts.map +1 -0
- package/dist/services/ServiceContext.mjs +2 -0
- package/dist/services/ServiceContext.mjs.map +1 -0
- package/dist/services/TradingReadinessCache.cjs +288 -0
- package/dist/services/TradingReadinessCache.cjs.map +1 -0
- package/dist/services/TradingReadinessCache.d.cts +174 -0
- package/dist/services/TradingReadinessCache.d.cts.map +1 -0
- package/dist/services/TradingReadinessCache.d.mts +174 -0
- package/dist/services/TradingReadinessCache.d.mts.map +1 -0
- package/dist/services/TradingReadinessCache.mjs +285 -0
- package/dist/services/TradingReadinessCache.mjs.map +1 -0
- package/dist/services/TradingService.cjs +1457 -0
- package/dist/services/TradingService.cjs.map +1 -0
- package/dist/services/TradingService.d.cts +195 -0
- package/dist/services/TradingService.d.cts.map +1 -0
- package/dist/services/TradingService.d.mts +195 -0
- package/dist/services/TradingService.d.mts.map +1 -0
- package/dist/services/TradingService.mjs +1453 -0
- package/dist/services/TradingService.mjs.map +1 -0
- package/dist/types/config.cjs +3 -0
- package/dist/types/config.cjs.map +1 -0
- package/dist/types/config.d.cts +49 -0
- package/dist/types/config.d.cts.map +1 -0
- package/dist/types/config.d.mts +49 -0
- package/dist/types/config.d.mts.map +1 -0
- package/dist/types/config.mjs +2 -0
- package/dist/types/config.mjs.map +1 -0
- package/dist/types/hyperliquid-types.cjs +3 -0
- package/dist/types/hyperliquid-types.cjs.map +1 -0
- package/dist/types/hyperliquid-types.d.cts +20 -0
- package/dist/types/hyperliquid-types.d.cts.map +1 -0
- package/dist/types/hyperliquid-types.d.mts +20 -0
- package/dist/types/hyperliquid-types.d.mts.map +1 -0
- package/dist/types/hyperliquid-types.mjs +2 -0
- package/dist/types/hyperliquid-types.mjs.map +1 -0
- package/dist/types/index.cjs +115 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +1262 -0
- package/dist/types/index.d.cts.map +1 -0
- package/dist/types/index.d.mts +1262 -0
- package/dist/types/index.d.mts.map +1 -0
- package/dist/types/index.mjs +97 -0
- package/dist/types/index.mjs.map +1 -0
- package/dist/types/messenger.cjs +3 -0
- package/dist/types/messenger.cjs.map +1 -0
- package/dist/types/messenger.d.cts +27 -0
- package/dist/types/messenger.d.cts.map +1 -0
- package/dist/types/messenger.d.mts +27 -0
- package/dist/types/messenger.d.mts.map +1 -0
- package/dist/types/messenger.mjs +2 -0
- package/dist/types/messenger.mjs.map +1 -0
- package/dist/types/myx-types.cjs +25 -0
- package/dist/types/myx-types.cjs.map +1 -0
- package/dist/types/myx-types.d.cts +63 -0
- package/dist/types/myx-types.d.cts.map +1 -0
- package/dist/types/myx-types.d.mts +63 -0
- package/dist/types/myx-types.d.mts.map +1 -0
- package/dist/types/myx-types.mjs +22 -0
- package/dist/types/myx-types.mjs.map +1 -0
- package/dist/types/perps-types.cjs +4 -0
- package/dist/types/perps-types.cjs.map +1 -0
- package/dist/types/perps-types.d.cts +105 -0
- package/dist/types/perps-types.d.cts.map +1 -0
- package/dist/types/perps-types.d.mts +105 -0
- package/dist/types/perps-types.d.mts.map +1 -0
- package/dist/types/perps-types.mjs +2 -0
- package/dist/types/perps-types.mjs.map +1 -0
- package/dist/types/token.cjs +3 -0
- package/dist/types/token.cjs.map +1 -0
- package/dist/types/token.d.cts +25 -0
- package/dist/types/token.d.cts.map +1 -0
- package/dist/types/token.d.mts +25 -0
- package/dist/types/token.d.mts.map +1 -0
- package/dist/types/token.mjs +2 -0
- package/dist/types/token.mjs.map +1 -0
- package/dist/types/transactionTypes.cjs +28 -0
- package/dist/types/transactionTypes.cjs.map +1 -0
- package/dist/types/transactionTypes.d.cts +64 -0
- package/dist/types/transactionTypes.d.cts.map +1 -0
- package/dist/types/transactionTypes.d.mts +64 -0
- package/dist/types/transactionTypes.d.mts.map +1 -0
- package/dist/types/transactionTypes.mjs +23 -0
- package/dist/types/transactionTypes.mjs.map +1 -0
- package/dist/utils/accountUtils.cjs +100 -0
- package/dist/utils/accountUtils.cjs.map +1 -0
- package/dist/utils/accountUtils.d.cts +30 -0
- package/dist/utils/accountUtils.d.cts.map +1 -0
- package/dist/utils/accountUtils.d.mts +30 -0
- package/dist/utils/accountUtils.d.mts.map +1 -0
- package/dist/utils/accountUtils.mjs +92 -0
- package/dist/utils/accountUtils.mjs.map +1 -0
- package/dist/utils/errorUtils.cjs +35 -0
- package/dist/utils/errorUtils.cjs.map +1 -0
- package/dist/utils/errorUtils.d.cts +15 -0
- package/dist/utils/errorUtils.d.cts.map +1 -0
- package/dist/utils/errorUtils.d.mts +15 -0
- package/dist/utils/errorUtils.d.mts.map +1 -0
- package/dist/utils/errorUtils.mjs +31 -0
- package/dist/utils/errorUtils.mjs.map +1 -0
- package/dist/utils/hyperLiquidAdapter.cjs +331 -0
- package/dist/utils/hyperLiquidAdapter.cjs.map +1 -0
- package/dist/utils/hyperLiquidAdapter.d.cts +42 -0
- package/dist/utils/hyperLiquidAdapter.d.cts.map +1 -0
- package/dist/utils/hyperLiquidAdapter.d.mts +42 -0
- package/dist/utils/hyperLiquidAdapter.d.mts.map +1 -0
- package/dist/utils/hyperLiquidAdapter.mjs +316 -0
- package/dist/utils/hyperLiquidAdapter.mjs.map +1 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.cjs +83 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.cjs.map +1 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.d.cts +55 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.d.cts.map +1 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.d.mts +55 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.d.mts.map +1 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.mjs +78 -0
- package/dist/utils/hyperLiquidOrderBookProcessor.mjs.map +1 -0
- package/dist/utils/hyperLiquidValidation.cjs +426 -0
- package/dist/utils/hyperLiquidValidation.cjs.map +1 -0
- package/dist/utils/hyperLiquidValidation.d.cts +143 -0
- package/dist/utils/hyperLiquidValidation.d.cts.map +1 -0
- package/dist/utils/hyperLiquidValidation.d.mts +143 -0
- package/dist/utils/hyperLiquidValidation.d.mts.map +1 -0
- package/dist/utils/hyperLiquidValidation.mjs +413 -0
- package/dist/utils/hyperLiquidValidation.mjs.map +1 -0
- package/dist/utils/idUtils.cjs +18 -0
- package/dist/utils/idUtils.cjs.map +1 -0
- package/dist/utils/idUtils.d.cts +6 -0
- package/dist/utils/idUtils.d.cts.map +1 -0
- package/dist/utils/idUtils.d.mts +6 -0
- package/dist/utils/idUtils.d.mts.map +1 -0
- package/dist/utils/idUtils.mjs +10 -0
- package/dist/utils/idUtils.mjs.map +1 -0
- package/dist/utils/index.cjs +59 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +25 -0
- package/dist/utils/index.d.cts.map +1 -0
- package/dist/utils/index.d.mts +25 -0
- package/dist/utils/index.d.mts.map +1 -0
- package/dist/utils/index.mjs +30 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/utils/marketDataTransform.cjs +211 -0
- package/dist/utils/marketDataTransform.cjs.map +1 -0
- package/dist/utils/marketDataTransform.d.cts +40 -0
- package/dist/utils/marketDataTransform.d.cts.map +1 -0
- package/dist/utils/marketDataTransform.d.mts +40 -0
- package/dist/utils/marketDataTransform.d.mts.map +1 -0
- package/dist/utils/marketDataTransform.mjs +205 -0
- package/dist/utils/marketDataTransform.mjs.map +1 -0
- package/dist/utils/marketUtils.cjs +151 -0
- package/dist/utils/marketUtils.cjs.map +1 -0
- package/dist/utils/marketUtils.d.cts +30 -0
- package/dist/utils/marketUtils.d.cts.map +1 -0
- package/dist/utils/marketUtils.d.mts +30 -0
- package/dist/utils/marketUtils.d.mts.map +1 -0
- package/dist/utils/marketUtils.mjs +138 -0
- package/dist/utils/marketUtils.mjs.map +1 -0
- package/dist/utils/myxAdapter.cjs +224 -0
- package/dist/utils/myxAdapter.cjs.map +1 -0
- package/dist/utils/myxAdapter.d.cts +81 -0
- package/dist/utils/myxAdapter.d.cts.map +1 -0
- package/dist/utils/myxAdapter.d.mts +81 -0
- package/dist/utils/myxAdapter.d.mts.map +1 -0
- package/dist/utils/myxAdapter.mjs +213 -0
- package/dist/utils/myxAdapter.mjs.map +1 -0
- package/dist/utils/orderCalculations.cjs +283 -0
- package/dist/utils/orderCalculations.cjs.map +1 -0
- package/dist/utils/orderCalculations.d.cts +107 -0
- package/dist/utils/orderCalculations.d.cts.map +1 -0
- package/dist/utils/orderCalculations.d.mts +107 -0
- package/dist/utils/orderCalculations.d.mts.map +1 -0
- package/dist/utils/orderCalculations.mjs +274 -0
- package/dist/utils/orderCalculations.mjs.map +1 -0
- package/dist/utils/rewardsUtils.cjs +98 -0
- package/dist/utils/rewardsUtils.cjs.map +1 -0
- package/dist/utils/rewardsUtils.d.cts +33 -0
- package/dist/utils/rewardsUtils.d.cts.map +1 -0
- package/dist/utils/rewardsUtils.d.mts +33 -0
- package/dist/utils/rewardsUtils.d.mts.map +1 -0
- package/dist/utils/rewardsUtils.mjs +92 -0
- package/dist/utils/rewardsUtils.mjs.map +1 -0
- package/dist/utils/significantFigures.cjs +88 -0
- package/dist/utils/significantFigures.cjs.map +1 -0
- package/dist/utils/significantFigures.d.cts +25 -0
- package/dist/utils/significantFigures.d.cts.map +1 -0
- package/dist/utils/significantFigures.d.mts +25 -0
- package/dist/utils/significantFigures.d.mts.map +1 -0
- package/dist/utils/significantFigures.mjs +82 -0
- package/dist/utils/significantFigures.mjs.map +1 -0
- package/dist/utils/sortMarkets.cjs +93 -0
- package/dist/utils/sortMarkets.cjs.map +1 -0
- package/dist/utils/sortMarkets.d.cts +27 -0
- package/dist/utils/sortMarkets.d.cts.map +1 -0
- package/dist/utils/sortMarkets.d.mts +27 -0
- package/dist/utils/sortMarkets.d.mts.map +1 -0
- package/dist/utils/sortMarkets.mjs +88 -0
- package/dist/utils/sortMarkets.mjs.map +1 -0
- package/dist/utils/standaloneInfoClient.cjs +70 -0
- package/dist/utils/standaloneInfoClient.cjs.map +1 -0
- package/dist/utils/standaloneInfoClient.d.cts +37 -0
- package/dist/utils/standaloneInfoClient.d.cts.map +1 -0
- package/dist/utils/standaloneInfoClient.d.mts +37 -0
- package/dist/utils/standaloneInfoClient.d.mts.map +1 -0
- package/dist/utils/standaloneInfoClient.mjs +64 -0
- package/dist/utils/standaloneInfoClient.mjs.map +1 -0
- package/dist/utils/stringParseUtils.cjs +18 -0
- package/dist/utils/stringParseUtils.cjs.map +1 -0
- package/dist/utils/stringParseUtils.d.cts +3 -0
- package/dist/utils/stringParseUtils.d.cts.map +1 -0
- package/dist/utils/stringParseUtils.d.mts +3 -0
- package/dist/utils/stringParseUtils.d.mts.map +1 -0
- package/dist/utils/stringParseUtils.mjs +13 -0
- package/dist/utils/stringParseUtils.mjs.map +1 -0
- package/dist/utils/transferData.cjs +33 -0
- package/dist/utils/transferData.cjs.map +1 -0
- package/dist/utils/transferData.d.cts +9 -0
- package/dist/utils/transferData.d.cts.map +1 -0
- package/dist/utils/transferData.d.mts +9 -0
- package/dist/utils/transferData.d.mts.map +1 -0
- package/dist/utils/transferData.mjs +29 -0
- package/dist/utils/transferData.mjs.map +1 -0
- package/dist/utils/wait.cjs +6 -0
- package/dist/utils/wait.cjs.map +1 -0
- package/dist/utils/wait.d.cts +2 -0
- package/dist/utils/wait.d.cts.map +1 -0
- package/dist/utils/wait.d.mts +2 -0
- package/dist/utils/wait.d.mts.map +1 -0
- package/dist/utils/wait.mjs +2 -0
- package/dist/utils/wait.mjs.map +1 -0
- package/package.json +16 -2
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
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");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _DepositService_deps, _DepositService_messenger;
|
|
13
|
+
import { toHex } from "@metamask/controller-utils";
|
|
14
|
+
import { parseCaipAssetId } from "@metamask/utils";
|
|
15
|
+
import { getSelectedEvmAccount } from "../utils/accountUtils.mjs";
|
|
16
|
+
import { generateDepositId } from "../utils/idUtils.mjs";
|
|
17
|
+
import { generateERC20TransferData } from "../utils/transferData.mjs";
|
|
18
|
+
// Temporary to avoid estimation failures due to insufficient balance
|
|
19
|
+
const DEPOSIT_GAS_LIMIT = toHex(100000);
|
|
20
|
+
/**
|
|
21
|
+
* DepositService
|
|
22
|
+
*
|
|
23
|
+
* Handles deposit transaction preparation and validation.
|
|
24
|
+
* Stateless service that prepares transaction data for TransactionController.
|
|
25
|
+
* Controller handles TransactionController integration and promise lifecycle.
|
|
26
|
+
*
|
|
27
|
+
* Instance-based service with constructor injection of platform dependencies
|
|
28
|
+
* and messenger for inter-controller communication.
|
|
29
|
+
*/
|
|
30
|
+
export class DepositService {
|
|
31
|
+
/**
|
|
32
|
+
* Create a new DepositService instance
|
|
33
|
+
*
|
|
34
|
+
* @param deps - Platform dependencies for logging, metrics, etc.
|
|
35
|
+
* @param messenger - Controller messenger for cross-controller communication.
|
|
36
|
+
*/
|
|
37
|
+
constructor(deps, messenger) {
|
|
38
|
+
_DepositService_deps.set(this, void 0);
|
|
39
|
+
_DepositService_messenger.set(this, void 0);
|
|
40
|
+
__classPrivateFieldSet(this, _DepositService_deps, deps, "f");
|
|
41
|
+
__classPrivateFieldSet(this, _DepositService_messenger, messenger, "f");
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Prepare deposit transaction for confirmation
|
|
45
|
+
* Extracts transaction construction logic from controller
|
|
46
|
+
*
|
|
47
|
+
* @param options - Configuration object
|
|
48
|
+
* @param options.provider - Active provider instance
|
|
49
|
+
* @returns Transaction data ready for TransactionController.addTransaction
|
|
50
|
+
*/
|
|
51
|
+
async prepareTransaction(options) {
|
|
52
|
+
const { provider } = options;
|
|
53
|
+
__classPrivateFieldGet(this, _DepositService_deps, "f").debugLogger.log('DepositService: Preparing deposit transaction');
|
|
54
|
+
// Generate deposit request ID for tracking
|
|
55
|
+
const currentDepositId = generateDepositId();
|
|
56
|
+
// Get deposit routes from provider
|
|
57
|
+
const depositRoutes = provider.getDepositRoutes({ isTestnet: false });
|
|
58
|
+
const route = depositRoutes[0];
|
|
59
|
+
const bridgeContractAddress = route.contractAddress;
|
|
60
|
+
// Generate transfer data for ERC-20 token transfer (portable, no mobile imports)
|
|
61
|
+
const transferData = generateERC20TransferData(bridgeContractAddress, '0x0');
|
|
62
|
+
// Get EVM account from selected account group via messenger
|
|
63
|
+
const evmAccount = getSelectedEvmAccount(__classPrivateFieldGet(this, _DepositService_messenger, "f").call('AccountTreeController:getAccountsFromSelectedAccountGroup'));
|
|
64
|
+
if (!evmAccount) {
|
|
65
|
+
throw new Error('No EVM-compatible account found in selected account group');
|
|
66
|
+
}
|
|
67
|
+
const accountAddress = evmAccount.address;
|
|
68
|
+
// Parse CAIP asset ID to extract chain ID and token address
|
|
69
|
+
const parsedAsset = parseCaipAssetId(route.assetId);
|
|
70
|
+
const assetChainId = toHex(parsedAsset.chainId.split(':')[1]);
|
|
71
|
+
const tokenAddress = parsedAsset.assetReference;
|
|
72
|
+
// Build transaction parameters for TransactionController
|
|
73
|
+
const transaction = {
|
|
74
|
+
from: accountAddress,
|
|
75
|
+
to: tokenAddress,
|
|
76
|
+
value: '0x0',
|
|
77
|
+
data: transferData,
|
|
78
|
+
gas: DEPOSIT_GAS_LIMIT,
|
|
79
|
+
};
|
|
80
|
+
__classPrivateFieldGet(this, _DepositService_deps, "f").debugLogger.log('DepositService: Deposit transaction prepared', {
|
|
81
|
+
depositId: currentDepositId,
|
|
82
|
+
assetChainId,
|
|
83
|
+
from: accountAddress,
|
|
84
|
+
to: tokenAddress,
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
transaction,
|
|
88
|
+
assetChainId,
|
|
89
|
+
currentDepositId,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
_DepositService_deps = new WeakMap(), _DepositService_messenger = new WeakMap();
|
|
94
|
+
//# sourceMappingURL=DepositService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DepositService.mjs","sourceRoot":"","sources":["../../src/services/DepositService.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,mCAAmC;AACnD,OAAO,EAAE,gBAAgB,EAAE,wBAAwB;AASnD,OAAO,EAAE,qBAAqB,EAAE,kCAA8B;AAC9D,OAAO,EAAE,iBAAiB,EAAE,6BAAyB;AACrD,OAAO,EAAE,yBAAyB,EAAE,kCAA8B;AAElE,qEAAqE;AACrE,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;AAExC;;;;;;;;;GASG;AACH,MAAM,OAAO,cAAc;IAKzB;;;;;OAKG;IACH,YACE,IAA+B,EAC/B,SAAuC;QAZhC,uCAAiC;QAEjC,4CAAyC;QAYhD,uBAAA,IAAI,wBAAS,IAAI,MAAA,CAAC;QAClB,uBAAA,IAAI,6BAAc,SAAS,MAAA,CAAC;IAC9B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,kBAAkB,CAAC,OAAoC;QAK3D,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAE7B,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;QAE5E,2CAA2C;QAC3C,MAAM,gBAAgB,GAAG,iBAAiB,EAAE,CAAC;QAE7C,mCAAmC;QACnC,MAAM,aAAa,GAAG,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,qBAAqB,GAAG,KAAK,CAAC,eAAe,CAAC;QAEpD,iFAAiF;QACjF,MAAM,YAAY,GAAG,yBAAyB,CAC5C,qBAAqB,EACrB,KAAK,CACN,CAAC;QAEF,4DAA4D;QAC5D,MAAM,UAAU,GAAG,qBAAqB,CACtC,uBAAA,IAAI,iCAAW,CAAC,IAAI,CAClB,2DAA2D,CAC5D,CACF,CAAC;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;QACJ,CAAC;QACD,MAAM,cAAc,GAAG,UAAU,CAAC,OAAc,CAAC;QAEjD,4DAA4D;QAC5D,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,YAAY,GAAG,WAAW,CAAC,cAAqB,CAAC;QAEvD,yDAAyD;QACzD,MAAM,WAAW,GAA2B;YAC1C,IAAI,EAAE,cAAc;YACpB,EAAE,EAAE,YAAY;YAChB,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,YAAY;YAClB,GAAG,EAAE,iBAAiB;SACvB,CAAC;QAEF,uBAAA,IAAI,4BAAM,CAAC,WAAW,CAAC,GAAG,CAAC,8CAA8C,EAAE;YACzE,SAAS,EAAE,gBAAgB;YAC3B,YAAY;YACZ,IAAI,EAAE,cAAc;YACpB,EAAE,EAAE,YAAY;SACjB,CAAC,CAAC;QAEH,OAAO;YACL,WAAW;YACX,YAAY;YACZ,gBAAgB;SACjB,CAAC;IACJ,CAAC;CACF","sourcesContent":["import { toHex } from '@metamask/controller-utils';\nimport { parseCaipAssetId } from '@metamask/utils';\nimport type { Hex } from '@metamask/utils';\n\nimport type {\n PerpsProvider,\n PerpsPlatformDependencies,\n PerpsTransactionParams,\n} from '../types';\nimport type { PerpsControllerMessengerBase } from '../types/messenger';\nimport { getSelectedEvmAccount } from '../utils/accountUtils';\nimport { generateDepositId } from '../utils/idUtils';\nimport { generateERC20TransferData } from '../utils/transferData';\n\n// Temporary to avoid estimation failures due to insufficient balance\nconst DEPOSIT_GAS_LIMIT = toHex(100000);\n\n/**\n * DepositService\n *\n * Handles deposit transaction preparation and validation.\n * Stateless service that prepares transaction data for TransactionController.\n * Controller handles TransactionController integration and promise lifecycle.\n *\n * Instance-based service with constructor injection of platform dependencies\n * and messenger for inter-controller communication.\n */\nexport class DepositService {\n readonly #deps: PerpsPlatformDependencies;\n\n readonly #messenger: PerpsControllerMessengerBase;\n\n /**\n * Create a new DepositService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n * @param messenger - Controller messenger for cross-controller communication.\n */\n constructor(\n deps: PerpsPlatformDependencies,\n messenger: PerpsControllerMessengerBase,\n ) {\n this.#deps = deps;\n this.#messenger = messenger;\n }\n\n /**\n * Prepare deposit transaction for confirmation\n * Extracts transaction construction logic from controller\n *\n * @param options - Configuration object\n * @param options.provider - Active provider instance\n * @returns Transaction data ready for TransactionController.addTransaction\n */\n async prepareTransaction(options: { provider: PerpsProvider }): Promise<{\n transaction: PerpsTransactionParams;\n assetChainId: Hex;\n currentDepositId: string;\n }> {\n const { provider } = options;\n\n this.#deps.debugLogger.log('DepositService: Preparing deposit transaction');\n\n // Generate deposit request ID for tracking\n const currentDepositId = generateDepositId();\n\n // Get deposit routes from provider\n const depositRoutes = provider.getDepositRoutes({ isTestnet: false });\n const route = depositRoutes[0];\n const bridgeContractAddress = route.contractAddress;\n\n // Generate transfer data for ERC-20 token transfer (portable, no mobile imports)\n const transferData = generateERC20TransferData(\n bridgeContractAddress,\n '0x0',\n );\n\n // Get EVM account from selected account group via messenger\n const evmAccount = getSelectedEvmAccount(\n this.#messenger.call(\n 'AccountTreeController:getAccountsFromSelectedAccountGroup',\n ),\n );\n if (!evmAccount) {\n throw new Error(\n 'No EVM-compatible account found in selected account group',\n );\n }\n const accountAddress = evmAccount.address as Hex;\n\n // Parse CAIP asset ID to extract chain ID and token address\n const parsedAsset = parseCaipAssetId(route.assetId);\n const assetChainId = toHex(parsedAsset.chainId.split(':')[1]);\n const tokenAddress = parsedAsset.assetReference as Hex;\n\n // Build transaction parameters for TransactionController\n const transaction: PerpsTransactionParams = {\n from: accountAddress,\n to: tokenAddress,\n value: '0x0',\n data: transferData,\n gas: DEPOSIT_GAS_LIMIT,\n };\n\n this.#deps.debugLogger.log('DepositService: Deposit transaction prepared', {\n depositId: currentDepositId,\n assetChainId,\n from: accountAddress,\n to: tokenAddress,\n });\n\n return {\n transaction,\n assetChainId,\n currentDepositId,\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
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");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _EligibilityService_instances, _EligibilityService_geoCacheTtlMs, _EligibilityService_deps, _EligibilityService_geoLocationCache, _EligibilityService_geoLocationFetchPromise, _EligibilityService_performGeoLocationFetch;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.EligibilityService = void 0;
|
|
16
|
+
const controller_utils_1 = require("@metamask/controller-utils");
|
|
17
|
+
const perpsConfig_1 = require("../constants/perpsConfig.cjs");
|
|
18
|
+
const utils_1 = require("../utils/index.cjs");
|
|
19
|
+
const errorUtils_1 = require("../utils/errorUtils.cjs");
|
|
20
|
+
// Geo-blocking API URLs
|
|
21
|
+
const ON_RAMP_GEO_BLOCKING_URLS = {
|
|
22
|
+
DEV: 'https://on-ramp.uat-api.cx.metamask.io/geolocation',
|
|
23
|
+
PROD: 'https://on-ramp.api.cx.metamask.io/geolocation',
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* EligibilityService
|
|
27
|
+
*
|
|
28
|
+
* Handles geo-location fetching and eligibility checking.
|
|
29
|
+
* Manages caching to minimize API calls.
|
|
30
|
+
*
|
|
31
|
+
* Instance-based service with constructor injection of platform dependencies.
|
|
32
|
+
* Cache is instance-scoped to support multiple service instances (e.g., testing).
|
|
33
|
+
*/
|
|
34
|
+
class EligibilityService {
|
|
35
|
+
/**
|
|
36
|
+
* Create a new EligibilityService instance
|
|
37
|
+
*
|
|
38
|
+
* @param deps - Platform dependencies for logging, metrics, etc.
|
|
39
|
+
*/
|
|
40
|
+
constructor(deps) {
|
|
41
|
+
_EligibilityService_instances.add(this);
|
|
42
|
+
_EligibilityService_geoCacheTtlMs.set(this, 5 * 60 * 1000); // 5 minutes
|
|
43
|
+
_EligibilityService_deps.set(this, void 0);
|
|
44
|
+
_EligibilityService_geoLocationCache.set(this, null);
|
|
45
|
+
_EligibilityService_geoLocationFetchPromise.set(this, null);
|
|
46
|
+
__classPrivateFieldSet(this, _EligibilityService_deps, deps, "f");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Fetch geo location with caching and deduplication
|
|
50
|
+
*
|
|
51
|
+
* @returns The user's geo location string.
|
|
52
|
+
*/
|
|
53
|
+
async fetchGeoLocation() {
|
|
54
|
+
// Check cache first
|
|
55
|
+
if (__classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f")) {
|
|
56
|
+
const cacheAge = Date.now() - __classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f").timestamp;
|
|
57
|
+
if (cacheAge < __classPrivateFieldGet(this, _EligibilityService_geoCacheTtlMs, "f")) {
|
|
58
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Using cached geo location', {
|
|
59
|
+
location: __classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f").location,
|
|
60
|
+
cacheAge: `${(cacheAge / 1000).toFixed(1)}s`,
|
|
61
|
+
});
|
|
62
|
+
return __classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f").location;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// If already fetching, return the existing promise
|
|
66
|
+
if (__classPrivateFieldGet(this, _EligibilityService_geoLocationFetchPromise, "f")) {
|
|
67
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Geo location fetch already in progress, waiting...');
|
|
68
|
+
return __classPrivateFieldGet(this, _EligibilityService_geoLocationFetchPromise, "f");
|
|
69
|
+
}
|
|
70
|
+
// Start new fetch
|
|
71
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationFetchPromise, __classPrivateFieldGet(this, _EligibilityService_instances, "m", _EligibilityService_performGeoLocationFetch).call(this), "f");
|
|
72
|
+
try {
|
|
73
|
+
const location = await __classPrivateFieldGet(this, _EligibilityService_geoLocationFetchPromise, "f");
|
|
74
|
+
return location;
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
// Clear the promise after completion (success or failure)
|
|
78
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationFetchPromise, null, "f");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if user is eligible based on geo-blocked regions
|
|
83
|
+
*
|
|
84
|
+
* @param options - The eligibility check parameters.
|
|
85
|
+
* @param options.blockedRegions - List of blocked region codes (e.g., ['US', 'CN']).
|
|
86
|
+
* @returns True if eligible (not in blocked region), false otherwise.
|
|
87
|
+
*/
|
|
88
|
+
async checkEligibility(options) {
|
|
89
|
+
const { blockedRegions } = options;
|
|
90
|
+
try {
|
|
91
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Checking eligibility', {
|
|
92
|
+
blockedRegionsCount: blockedRegions.length,
|
|
93
|
+
});
|
|
94
|
+
// Returns UNKNOWN if we can't fetch the geo location
|
|
95
|
+
const geoLocation = await this.fetchGeoLocation();
|
|
96
|
+
// Only set to eligible if we have valid geolocation and it's not blocked
|
|
97
|
+
if (geoLocation !== 'UNKNOWN') {
|
|
98
|
+
const isEligible = blockedRegions.every((geoBlockedRegion) => !geoLocation
|
|
99
|
+
.toUpperCase()
|
|
100
|
+
.startsWith(geoBlockedRegion.toUpperCase()));
|
|
101
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Eligibility check completed', {
|
|
102
|
+
geoLocation,
|
|
103
|
+
isEligible,
|
|
104
|
+
blockedRegions,
|
|
105
|
+
});
|
|
106
|
+
return isEligible;
|
|
107
|
+
}
|
|
108
|
+
// Default to eligible if location is unknown
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").logger.error((0, errorUtils_1.ensureError)(error, 'EligibilityService.checkEligibility'), {
|
|
113
|
+
tags: { feature: perpsConfig_1.PERPS_CONSTANTS.FeatureName },
|
|
114
|
+
context: {
|
|
115
|
+
name: 'EligibilityService.checkEligibility',
|
|
116
|
+
data: {},
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
// Default to eligible on error
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Clear the geo-location cache
|
|
125
|
+
* Useful for testing or forcing a fresh fetch
|
|
126
|
+
*/
|
|
127
|
+
clearCache() {
|
|
128
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationCache, null, "f");
|
|
129
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationFetchPromise, null, "f");
|
|
130
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Cache cleared');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
exports.EligibilityService = EligibilityService;
|
|
134
|
+
_EligibilityService_geoCacheTtlMs = new WeakMap(), _EligibilityService_deps = new WeakMap(), _EligibilityService_geoLocationCache = new WeakMap(), _EligibilityService_geoLocationFetchPromise = new WeakMap(), _EligibilityService_instances = new WeakSet(), _EligibilityService_performGeoLocationFetch =
|
|
135
|
+
/**
|
|
136
|
+
* Perform the actual geo location fetch
|
|
137
|
+
* Separated to allow proper promise management
|
|
138
|
+
*
|
|
139
|
+
* @returns The fetched geo location string, or 'UNKNOWN' on failure.
|
|
140
|
+
*/
|
|
141
|
+
async function _EligibilityService_performGeoLocationFetch() {
|
|
142
|
+
let location = 'UNKNOWN';
|
|
143
|
+
try {
|
|
144
|
+
const environment = (0, utils_1.getEnvironment)();
|
|
145
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Fetching geo location from API', {
|
|
146
|
+
environment,
|
|
147
|
+
});
|
|
148
|
+
const response = await (0, controller_utils_1.successfulFetch)(ON_RAMP_GEO_BLOCKING_URLS[environment]);
|
|
149
|
+
const textResult = await response?.text();
|
|
150
|
+
location = textResult || 'UNKNOWN';
|
|
151
|
+
// Cache the successful result
|
|
152
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationCache, {
|
|
153
|
+
location,
|
|
154
|
+
timestamp: Date.now(),
|
|
155
|
+
}, "f");
|
|
156
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Geo location fetched successfully', {
|
|
157
|
+
location,
|
|
158
|
+
});
|
|
159
|
+
return location;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").logger.error((0, errorUtils_1.ensureError)(error, 'EligibilityService.performGeoLocationFetch'), {
|
|
163
|
+
tags: { feature: perpsConfig_1.PERPS_CONSTANTS.FeatureName },
|
|
164
|
+
context: {
|
|
165
|
+
name: 'EligibilityService.performGeoLocationFetch',
|
|
166
|
+
data: {},
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
// Don't cache failures
|
|
170
|
+
return location;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
//# sourceMappingURL=EligibilityService.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EligibilityService.cjs","sourceRoot":"","sources":["../../src/services/EligibilityService.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig';\nimport type {\n PerpsPlatformDependencies,\n CheckEligibilityParams,\n} from '../types';\nimport { getEnvironment } from '../utils';\nimport { ensureError } from '../utils/errorUtils';\n\n// Geo-blocking API URLs\nconst ON_RAMP_GEO_BLOCKING_URLS = {\n DEV: 'https://on-ramp.uat-api.cx.metamask.io/geolocation',\n PROD: 'https://on-ramp.api.cx.metamask.io/geolocation',\n} as const;\n\n/**\n * Geo-location cache entry\n */\ntype GeoLocationCache = {\n location: string;\n timestamp: number;\n};\n\n/**\n * EligibilityService\n *\n * Handles geo-location fetching and eligibility checking.\n * Manages caching to minimize API calls.\n *\n * Instance-based service with constructor injection of platform dependencies.\n * Cache is instance-scoped to support multiple service instances (e.g., testing).\n */\nexport class EligibilityService {\n readonly #geoCacheTtlMs = 5 * 60 * 1000; // 5 minutes\n\n readonly #deps: PerpsPlatformDependencies;\n\n #geoLocationCache: GeoLocationCache | null = null;\n\n #geoLocationFetchPromise: Promise<string> | null = null;\n\n /**\n * Create a new EligibilityService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n */\n constructor(deps: PerpsPlatformDependencies) {\n this.#deps = deps;\n }\n\n /**\n * Fetch geo location with caching and deduplication\n *\n * @returns The user's geo location string.\n */\n async fetchGeoLocation(): Promise<string> {\n // Check cache first\n if (this.#geoLocationCache) {\n const cacheAge = Date.now() - this.#geoLocationCache.timestamp;\n if (cacheAge < this.#geoCacheTtlMs) {\n this.#deps.debugLogger.log(\n 'EligibilityService: Using cached geo location',\n {\n location: this.#geoLocationCache.location,\n cacheAge: `${(cacheAge / 1000).toFixed(1)}s`,\n },\n );\n return this.#geoLocationCache.location;\n }\n }\n\n // If already fetching, return the existing promise\n if (this.#geoLocationFetchPromise) {\n this.#deps.debugLogger.log(\n 'EligibilityService: Geo location fetch already in progress, waiting...',\n );\n return this.#geoLocationFetchPromise;\n }\n\n // Start new fetch\n this.#geoLocationFetchPromise = this.#performGeoLocationFetch();\n\n try {\n const location = await this.#geoLocationFetchPromise;\n return location;\n } finally {\n // Clear the promise after completion (success or failure)\n this.#geoLocationFetchPromise = null;\n }\n }\n\n /**\n * Perform the actual geo location fetch\n * Separated to allow proper promise management\n *\n * @returns The fetched geo location string, or 'UNKNOWN' on failure.\n */\n async #performGeoLocationFetch(): Promise<string> {\n let location = 'UNKNOWN';\n\n try {\n const environment = getEnvironment();\n\n this.#deps.debugLogger.log(\n 'EligibilityService: Fetching geo location from API',\n {\n environment,\n },\n );\n\n const response = await successfulFetch(\n ON_RAMP_GEO_BLOCKING_URLS[environment],\n );\n\n const textResult = await response?.text();\n location = textResult || 'UNKNOWN';\n\n // Cache the successful result\n this.#geoLocationCache = {\n location,\n timestamp: Date.now(),\n };\n\n this.#deps.debugLogger.log(\n 'EligibilityService: Geo location fetched successfully',\n {\n location,\n },\n );\n\n return location;\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'EligibilityService.performGeoLocationFetch'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'EligibilityService.performGeoLocationFetch',\n data: {},\n },\n },\n );\n // Don't cache failures\n return location;\n }\n }\n\n /**\n * Check if user is eligible based on geo-blocked regions\n *\n * @param options - The eligibility check parameters.\n * @param options.blockedRegions - List of blocked region codes (e.g., ['US', 'CN']).\n * @returns True if eligible (not in blocked region), false otherwise.\n */\n async checkEligibility(options: CheckEligibilityParams): Promise<boolean> {\n const { blockedRegions } = options;\n try {\n this.#deps.debugLogger.log('EligibilityService: Checking eligibility', {\n blockedRegionsCount: blockedRegions.length,\n });\n\n // Returns UNKNOWN if we can't fetch the geo location\n const geoLocation = await this.fetchGeoLocation();\n\n // Only set to eligible if we have valid geolocation and it's not blocked\n if (geoLocation !== 'UNKNOWN') {\n const isEligible = blockedRegions.every(\n (geoBlockedRegion) =>\n !geoLocation\n .toUpperCase()\n .startsWith(geoBlockedRegion.toUpperCase()),\n );\n\n this.#deps.debugLogger.log(\n 'EligibilityService: Eligibility check completed',\n {\n geoLocation,\n isEligible,\n blockedRegions,\n },\n );\n\n return isEligible;\n }\n\n // Default to eligible if location is unknown\n return true;\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'EligibilityService.checkEligibility'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'EligibilityService.checkEligibility',\n data: {},\n },\n },\n );\n // Default to eligible on error\n return true;\n }\n }\n\n /**\n * Clear the geo-location cache\n * Useful for testing or forcing a fresh fetch\n */\n clearCache(): void {\n this.#geoLocationCache = null;\n this.#geoLocationFetchPromise = null;\n this.#deps.debugLogger.log('EligibilityService: Cache cleared');\n }\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PerpsPlatformDependencies, CheckEligibilityParams } from "../types/index.cjs";
|
|
2
|
+
/**
|
|
3
|
+
* EligibilityService
|
|
4
|
+
*
|
|
5
|
+
* Handles geo-location fetching and eligibility checking.
|
|
6
|
+
* Manages caching to minimize API calls.
|
|
7
|
+
*
|
|
8
|
+
* Instance-based service with constructor injection of platform dependencies.
|
|
9
|
+
* Cache is instance-scoped to support multiple service instances (e.g., testing).
|
|
10
|
+
*/
|
|
11
|
+
export declare class EligibilityService {
|
|
12
|
+
#private;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new EligibilityService instance
|
|
15
|
+
*
|
|
16
|
+
* @param deps - Platform dependencies for logging, metrics, etc.
|
|
17
|
+
*/
|
|
18
|
+
constructor(deps: PerpsPlatformDependencies);
|
|
19
|
+
/**
|
|
20
|
+
* Fetch geo location with caching and deduplication
|
|
21
|
+
*
|
|
22
|
+
* @returns The user's geo location string.
|
|
23
|
+
*/
|
|
24
|
+
fetchGeoLocation(): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Check if user is eligible based on geo-blocked regions
|
|
27
|
+
*
|
|
28
|
+
* @param options - The eligibility check parameters.
|
|
29
|
+
* @param options.blockedRegions - List of blocked region codes (e.g., ['US', 'CN']).
|
|
30
|
+
* @returns True if eligible (not in blocked region), false otherwise.
|
|
31
|
+
*/
|
|
32
|
+
checkEligibility(options: CheckEligibilityParams): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Clear the geo-location cache
|
|
35
|
+
* Useful for testing or forcing a fresh fetch
|
|
36
|
+
*/
|
|
37
|
+
clearCache(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=EligibilityService.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EligibilityService.d.cts","sourceRoot":"","sources":["../../src/services/EligibilityService.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACvB,2BAAiB;AAkBlB;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;;IAS7B;;;;OAIG;gBACS,IAAI,EAAE,yBAAyB;IAI3C;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IA4FzC;;;;;;OAMG;IACG,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDzE;;;OAGG;IACH,UAAU,IAAI,IAAI;CAKnB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { PerpsPlatformDependencies, CheckEligibilityParams } from "../types/index.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* EligibilityService
|
|
4
|
+
*
|
|
5
|
+
* Handles geo-location fetching and eligibility checking.
|
|
6
|
+
* Manages caching to minimize API calls.
|
|
7
|
+
*
|
|
8
|
+
* Instance-based service with constructor injection of platform dependencies.
|
|
9
|
+
* Cache is instance-scoped to support multiple service instances (e.g., testing).
|
|
10
|
+
*/
|
|
11
|
+
export declare class EligibilityService {
|
|
12
|
+
#private;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new EligibilityService instance
|
|
15
|
+
*
|
|
16
|
+
* @param deps - Platform dependencies for logging, metrics, etc.
|
|
17
|
+
*/
|
|
18
|
+
constructor(deps: PerpsPlatformDependencies);
|
|
19
|
+
/**
|
|
20
|
+
* Fetch geo location with caching and deduplication
|
|
21
|
+
*
|
|
22
|
+
* @returns The user's geo location string.
|
|
23
|
+
*/
|
|
24
|
+
fetchGeoLocation(): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Check if user is eligible based on geo-blocked regions
|
|
27
|
+
*
|
|
28
|
+
* @param options - The eligibility check parameters.
|
|
29
|
+
* @param options.blockedRegions - List of blocked region codes (e.g., ['US', 'CN']).
|
|
30
|
+
* @returns True if eligible (not in blocked region), false otherwise.
|
|
31
|
+
*/
|
|
32
|
+
checkEligibility(options: CheckEligibilityParams): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Clear the geo-location cache
|
|
35
|
+
* Useful for testing or forcing a fresh fetch
|
|
36
|
+
*/
|
|
37
|
+
clearCache(): void;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=EligibilityService.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EligibilityService.d.mts","sourceRoot":"","sources":["../../src/services/EligibilityService.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACvB,2BAAiB;AAkBlB;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;;IAS7B;;;;OAIG;gBACS,IAAI,EAAE,yBAAyB;IAI3C;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;IA4FzC;;;;;;OAMG;IACG,gBAAgB,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDzE;;;OAGG;IACH,UAAU,IAAI,IAAI;CAKnB"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
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");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _EligibilityService_instances, _EligibilityService_geoCacheTtlMs, _EligibilityService_deps, _EligibilityService_geoLocationCache, _EligibilityService_geoLocationFetchPromise, _EligibilityService_performGeoLocationFetch;
|
|
13
|
+
import { successfulFetch } from "@metamask/controller-utils";
|
|
14
|
+
import { PERPS_CONSTANTS } from "../constants/perpsConfig.mjs";
|
|
15
|
+
import { getEnvironment } from "../utils/index.mjs";
|
|
16
|
+
import { ensureError } from "../utils/errorUtils.mjs";
|
|
17
|
+
// Geo-blocking API URLs
|
|
18
|
+
const ON_RAMP_GEO_BLOCKING_URLS = {
|
|
19
|
+
DEV: 'https://on-ramp.uat-api.cx.metamask.io/geolocation',
|
|
20
|
+
PROD: 'https://on-ramp.api.cx.metamask.io/geolocation',
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* EligibilityService
|
|
24
|
+
*
|
|
25
|
+
* Handles geo-location fetching and eligibility checking.
|
|
26
|
+
* Manages caching to minimize API calls.
|
|
27
|
+
*
|
|
28
|
+
* Instance-based service with constructor injection of platform dependencies.
|
|
29
|
+
* Cache is instance-scoped to support multiple service instances (e.g., testing).
|
|
30
|
+
*/
|
|
31
|
+
export class EligibilityService {
|
|
32
|
+
/**
|
|
33
|
+
* Create a new EligibilityService instance
|
|
34
|
+
*
|
|
35
|
+
* @param deps - Platform dependencies for logging, metrics, etc.
|
|
36
|
+
*/
|
|
37
|
+
constructor(deps) {
|
|
38
|
+
_EligibilityService_instances.add(this);
|
|
39
|
+
_EligibilityService_geoCacheTtlMs.set(this, 5 * 60 * 1000); // 5 minutes
|
|
40
|
+
_EligibilityService_deps.set(this, void 0);
|
|
41
|
+
_EligibilityService_geoLocationCache.set(this, null);
|
|
42
|
+
_EligibilityService_geoLocationFetchPromise.set(this, null);
|
|
43
|
+
__classPrivateFieldSet(this, _EligibilityService_deps, deps, "f");
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Fetch geo location with caching and deduplication
|
|
47
|
+
*
|
|
48
|
+
* @returns The user's geo location string.
|
|
49
|
+
*/
|
|
50
|
+
async fetchGeoLocation() {
|
|
51
|
+
// Check cache first
|
|
52
|
+
if (__classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f")) {
|
|
53
|
+
const cacheAge = Date.now() - __classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f").timestamp;
|
|
54
|
+
if (cacheAge < __classPrivateFieldGet(this, _EligibilityService_geoCacheTtlMs, "f")) {
|
|
55
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Using cached geo location', {
|
|
56
|
+
location: __classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f").location,
|
|
57
|
+
cacheAge: `${(cacheAge / 1000).toFixed(1)}s`,
|
|
58
|
+
});
|
|
59
|
+
return __classPrivateFieldGet(this, _EligibilityService_geoLocationCache, "f").location;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// If already fetching, return the existing promise
|
|
63
|
+
if (__classPrivateFieldGet(this, _EligibilityService_geoLocationFetchPromise, "f")) {
|
|
64
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Geo location fetch already in progress, waiting...');
|
|
65
|
+
return __classPrivateFieldGet(this, _EligibilityService_geoLocationFetchPromise, "f");
|
|
66
|
+
}
|
|
67
|
+
// Start new fetch
|
|
68
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationFetchPromise, __classPrivateFieldGet(this, _EligibilityService_instances, "m", _EligibilityService_performGeoLocationFetch).call(this), "f");
|
|
69
|
+
try {
|
|
70
|
+
const location = await __classPrivateFieldGet(this, _EligibilityService_geoLocationFetchPromise, "f");
|
|
71
|
+
return location;
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
// Clear the promise after completion (success or failure)
|
|
75
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationFetchPromise, null, "f");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if user is eligible based on geo-blocked regions
|
|
80
|
+
*
|
|
81
|
+
* @param options - The eligibility check parameters.
|
|
82
|
+
* @param options.blockedRegions - List of blocked region codes (e.g., ['US', 'CN']).
|
|
83
|
+
* @returns True if eligible (not in blocked region), false otherwise.
|
|
84
|
+
*/
|
|
85
|
+
async checkEligibility(options) {
|
|
86
|
+
const { blockedRegions } = options;
|
|
87
|
+
try {
|
|
88
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Checking eligibility', {
|
|
89
|
+
blockedRegionsCount: blockedRegions.length,
|
|
90
|
+
});
|
|
91
|
+
// Returns UNKNOWN if we can't fetch the geo location
|
|
92
|
+
const geoLocation = await this.fetchGeoLocation();
|
|
93
|
+
// Only set to eligible if we have valid geolocation and it's not blocked
|
|
94
|
+
if (geoLocation !== 'UNKNOWN') {
|
|
95
|
+
const isEligible = blockedRegions.every((geoBlockedRegion) => !geoLocation
|
|
96
|
+
.toUpperCase()
|
|
97
|
+
.startsWith(geoBlockedRegion.toUpperCase()));
|
|
98
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Eligibility check completed', {
|
|
99
|
+
geoLocation,
|
|
100
|
+
isEligible,
|
|
101
|
+
blockedRegions,
|
|
102
|
+
});
|
|
103
|
+
return isEligible;
|
|
104
|
+
}
|
|
105
|
+
// Default to eligible if location is unknown
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").logger.error(ensureError(error, 'EligibilityService.checkEligibility'), {
|
|
110
|
+
tags: { feature: PERPS_CONSTANTS.FeatureName },
|
|
111
|
+
context: {
|
|
112
|
+
name: 'EligibilityService.checkEligibility',
|
|
113
|
+
data: {},
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
// Default to eligible on error
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear the geo-location cache
|
|
122
|
+
* Useful for testing or forcing a fresh fetch
|
|
123
|
+
*/
|
|
124
|
+
clearCache() {
|
|
125
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationCache, null, "f");
|
|
126
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationFetchPromise, null, "f");
|
|
127
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Cache cleared');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
_EligibilityService_geoCacheTtlMs = new WeakMap(), _EligibilityService_deps = new WeakMap(), _EligibilityService_geoLocationCache = new WeakMap(), _EligibilityService_geoLocationFetchPromise = new WeakMap(), _EligibilityService_instances = new WeakSet(), _EligibilityService_performGeoLocationFetch =
|
|
131
|
+
/**
|
|
132
|
+
* Perform the actual geo location fetch
|
|
133
|
+
* Separated to allow proper promise management
|
|
134
|
+
*
|
|
135
|
+
* @returns The fetched geo location string, or 'UNKNOWN' on failure.
|
|
136
|
+
*/
|
|
137
|
+
async function _EligibilityService_performGeoLocationFetch() {
|
|
138
|
+
let location = 'UNKNOWN';
|
|
139
|
+
try {
|
|
140
|
+
const environment = getEnvironment();
|
|
141
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Fetching geo location from API', {
|
|
142
|
+
environment,
|
|
143
|
+
});
|
|
144
|
+
const response = await successfulFetch(ON_RAMP_GEO_BLOCKING_URLS[environment]);
|
|
145
|
+
const textResult = await response?.text();
|
|
146
|
+
location = textResult || 'UNKNOWN';
|
|
147
|
+
// Cache the successful result
|
|
148
|
+
__classPrivateFieldSet(this, _EligibilityService_geoLocationCache, {
|
|
149
|
+
location,
|
|
150
|
+
timestamp: Date.now(),
|
|
151
|
+
}, "f");
|
|
152
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").debugLogger.log('EligibilityService: Geo location fetched successfully', {
|
|
153
|
+
location,
|
|
154
|
+
});
|
|
155
|
+
return location;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
__classPrivateFieldGet(this, _EligibilityService_deps, "f").logger.error(ensureError(error, 'EligibilityService.performGeoLocationFetch'), {
|
|
159
|
+
tags: { feature: PERPS_CONSTANTS.FeatureName },
|
|
160
|
+
context: {
|
|
161
|
+
name: 'EligibilityService.performGeoLocationFetch',
|
|
162
|
+
data: {},
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
// Don't cache failures
|
|
166
|
+
return location;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=EligibilityService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EligibilityService.mjs","sourceRoot":"","sources":["../../src/services/EligibilityService.ts"],"names":[],"mappings":"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","sourcesContent":["import { successfulFetch } from '@metamask/controller-utils';\n\nimport { PERPS_CONSTANTS } from '../constants/perpsConfig';\nimport type {\n PerpsPlatformDependencies,\n CheckEligibilityParams,\n} from '../types';\nimport { getEnvironment } from '../utils';\nimport { ensureError } from '../utils/errorUtils';\n\n// Geo-blocking API URLs\nconst ON_RAMP_GEO_BLOCKING_URLS = {\n DEV: 'https://on-ramp.uat-api.cx.metamask.io/geolocation',\n PROD: 'https://on-ramp.api.cx.metamask.io/geolocation',\n} as const;\n\n/**\n * Geo-location cache entry\n */\ntype GeoLocationCache = {\n location: string;\n timestamp: number;\n};\n\n/**\n * EligibilityService\n *\n * Handles geo-location fetching and eligibility checking.\n * Manages caching to minimize API calls.\n *\n * Instance-based service with constructor injection of platform dependencies.\n * Cache is instance-scoped to support multiple service instances (e.g., testing).\n */\nexport class EligibilityService {\n readonly #geoCacheTtlMs = 5 * 60 * 1000; // 5 minutes\n\n readonly #deps: PerpsPlatformDependencies;\n\n #geoLocationCache: GeoLocationCache | null = null;\n\n #geoLocationFetchPromise: Promise<string> | null = null;\n\n /**\n * Create a new EligibilityService instance\n *\n * @param deps - Platform dependencies for logging, metrics, etc.\n */\n constructor(deps: PerpsPlatformDependencies) {\n this.#deps = deps;\n }\n\n /**\n * Fetch geo location with caching and deduplication\n *\n * @returns The user's geo location string.\n */\n async fetchGeoLocation(): Promise<string> {\n // Check cache first\n if (this.#geoLocationCache) {\n const cacheAge = Date.now() - this.#geoLocationCache.timestamp;\n if (cacheAge < this.#geoCacheTtlMs) {\n this.#deps.debugLogger.log(\n 'EligibilityService: Using cached geo location',\n {\n location: this.#geoLocationCache.location,\n cacheAge: `${(cacheAge / 1000).toFixed(1)}s`,\n },\n );\n return this.#geoLocationCache.location;\n }\n }\n\n // If already fetching, return the existing promise\n if (this.#geoLocationFetchPromise) {\n this.#deps.debugLogger.log(\n 'EligibilityService: Geo location fetch already in progress, waiting...',\n );\n return this.#geoLocationFetchPromise;\n }\n\n // Start new fetch\n this.#geoLocationFetchPromise = this.#performGeoLocationFetch();\n\n try {\n const location = await this.#geoLocationFetchPromise;\n return location;\n } finally {\n // Clear the promise after completion (success or failure)\n this.#geoLocationFetchPromise = null;\n }\n }\n\n /**\n * Perform the actual geo location fetch\n * Separated to allow proper promise management\n *\n * @returns The fetched geo location string, or 'UNKNOWN' on failure.\n */\n async #performGeoLocationFetch(): Promise<string> {\n let location = 'UNKNOWN';\n\n try {\n const environment = getEnvironment();\n\n this.#deps.debugLogger.log(\n 'EligibilityService: Fetching geo location from API',\n {\n environment,\n },\n );\n\n const response = await successfulFetch(\n ON_RAMP_GEO_BLOCKING_URLS[environment],\n );\n\n const textResult = await response?.text();\n location = textResult || 'UNKNOWN';\n\n // Cache the successful result\n this.#geoLocationCache = {\n location,\n timestamp: Date.now(),\n };\n\n this.#deps.debugLogger.log(\n 'EligibilityService: Geo location fetched successfully',\n {\n location,\n },\n );\n\n return location;\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'EligibilityService.performGeoLocationFetch'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'EligibilityService.performGeoLocationFetch',\n data: {},\n },\n },\n );\n // Don't cache failures\n return location;\n }\n }\n\n /**\n * Check if user is eligible based on geo-blocked regions\n *\n * @param options - The eligibility check parameters.\n * @param options.blockedRegions - List of blocked region codes (e.g., ['US', 'CN']).\n * @returns True if eligible (not in blocked region), false otherwise.\n */\n async checkEligibility(options: CheckEligibilityParams): Promise<boolean> {\n const { blockedRegions } = options;\n try {\n this.#deps.debugLogger.log('EligibilityService: Checking eligibility', {\n blockedRegionsCount: blockedRegions.length,\n });\n\n // Returns UNKNOWN if we can't fetch the geo location\n const geoLocation = await this.fetchGeoLocation();\n\n // Only set to eligible if we have valid geolocation and it's not blocked\n if (geoLocation !== 'UNKNOWN') {\n const isEligible = blockedRegions.every(\n (geoBlockedRegion) =>\n !geoLocation\n .toUpperCase()\n .startsWith(geoBlockedRegion.toUpperCase()),\n );\n\n this.#deps.debugLogger.log(\n 'EligibilityService: Eligibility check completed',\n {\n geoLocation,\n isEligible,\n blockedRegions,\n },\n );\n\n return isEligible;\n }\n\n // Default to eligible if location is unknown\n return true;\n } catch (error) {\n this.#deps.logger.error(\n ensureError(error, 'EligibilityService.checkEligibility'),\n {\n tags: { feature: PERPS_CONSTANTS.FeatureName },\n context: {\n name: 'EligibilityService.checkEligibility',\n data: {},\n },\n },\n );\n // Default to eligible on error\n return true;\n }\n }\n\n /**\n * Clear the geo-location cache\n * Useful for testing or forcing a fresh fetch\n */\n clearCache(): void {\n this.#geoLocationCache = null;\n this.#geoLocationFetchPromise = null;\n this.#deps.debugLogger.log('EligibilityService: Cache cleared');\n }\n}\n"]}
|