Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ export function getSubscriptionServiceMessenger(
'SubscriptionController:getBillingPortalUrl',
'SubscriptionController:submitSponsorshipIntents',
'SubscriptionController:getState',
'SubscriptionController:submitShieldSubscriptionCryptoApproval',
'SubscriptionController:linkRewards',
'AppStateController:getState',
'AppStateController:setPendingShieldCohort',
'AuthenticationController:getBearerToken',
'TransactionController:getTransactions',
'AccountsController:getState',
Expand All @@ -50,6 +53,10 @@ export function getSubscriptionServiceMessenger(
'SwapsController:getState',
'MetaMetricsController:trackEvent',
'KeyringController:getState',
// Rewards Integration
'RewardsController:getSeasonStatus',
'RewardsController:getSeasonMetadata',
'RewardsController:getActualSubscriptionId',
],
});
return serviceMessenger;
Expand Down
13 changes: 12 additions & 1 deletion app/scripts/controllers/app-state-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,20 @@ export type AppStateControllerSetCanTrackWalletFundsObtainedAction = {
handler: AppStateController['setCanTrackWalletFundsObtained'];
};

export type AppStateControllerSetPendingShieldCohortAction = {
type: 'AppStateController:setPendingShieldCohort';
handler: AppStateController['setPendingShieldCohort'];
};

/**
* Actions exposed by the {@link AppStateController}.
*/
export type AppStateControllerActions =
| AppStateControllerGetStateAction
| AppStateControllerGetUnlockPromiseAction
| AppStateControllerRequestQrCodeScanAction
| AppStateControllerSetCanTrackWalletFundsObtainedAction;
| AppStateControllerSetCanTrackWalletFundsObtainedAction
| AppStateControllerSetPendingShieldCohortAction;

/**
* Actions that this controller is allowed to call.
Expand Down Expand Up @@ -773,6 +779,11 @@ export class AppStateController extends BaseController<
this.setCanTrackWalletFundsObtained.bind(this),
);

this.messenger.registerActionHandler(
'AppStateController:setPendingShieldCohort',
this.setPendingShieldCohort.bind(this),
);

this.#approvalRequestId = null;
}

Expand Down
78 changes: 9 additions & 69 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ import {
SecretType,
RecoveryError,
} from '@metamask/seedless-onboarding-controller';
import { COHORT_NAMES, PRODUCT_TYPES } from '@metamask/subscription-controller';
import { PRODUCT_TYPES } from '@metamask/subscription-controller';
import { isSnapId } from '@metamask/snaps-utils';
import {
findAtomicBatchSupportForChain,
Expand Down Expand Up @@ -911,11 +911,11 @@ export default class MetamaskController extends EventEmitter {
this.controllerMessenger.subscribe(
'TransactionController:transactionSubmitted',
({ transactionMeta }) => {
this._onShieldSubscriptionApprovalTransaction(transactionMeta).catch(
(err) => {
this.subscriptionService
.handlePostTransaction(transactionMeta)
.catch((err) => {
console.error('Error onShieldSubscriptionApprovalTransaction', err);
},
);
});
},
);

Expand Down Expand Up @@ -2607,10 +2607,6 @@ export default class MetamaskController extends EventEmitter {
this.subscriptionService.updateSubscriptionCardPaymentMethod.bind(
this.subscriptionService,
),
startSubscriptionWithCrypto:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing since, this API is not being used by JSON RPC Engine.

this.subscriptionController.startSubscriptionWithCrypto.bind(
this.subscriptionController,
),
updateSubscriptionCryptoPaymentMethod:
this.subscriptionService.updateSubscriptionCryptoPaymentMethod.bind(
this.subscriptionService,
Expand All @@ -2619,6 +2615,10 @@ export default class MetamaskController extends EventEmitter {
this.subscriptionController.submitUserEvent.bind(
this.subscriptionController,
),
linkRewardToShieldSubscription:
this.subscriptionService.linkRewardToExistingSubscription.bind(
this.subscriptionService,
),

// rewards
getRewardsCandidateSubscriptionId:
Expand Down Expand Up @@ -8643,66 +8643,6 @@ export default class MetamaskController extends EventEmitter {
});
}

/**
* Handles the shield subscription approval transaction after confirm
* NOTE: This doesn't subscribe to messenger internally inside controller because we need more info from the client as params
*
* @param transactionMeta - The transaction metadata.
*/
async _onShieldSubscriptionApprovalTransaction(transactionMeta) {
Copy link
Contributor Author

@lwin-kyaw lwin-kyaw Dec 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored this to SubscriptionService handleShieldSubscriptionApprovalTransaction

const { isGasFeeSponsored, chainId } = transactionMeta;
const bundlerSupported = await isSendBundleSupported(chainId);
const isSponsored = isGasFeeSponsored && bundlerSupported;

try {
this.subscriptionService.trackSubscriptionRequestEvent(
'started',
transactionMeta,
{
has_sufficient_crypto_balance: true,
},
);

await this.subscriptionController.submitShieldSubscriptionCryptoApproval(
transactionMeta,
isSponsored,
);

// Mark send/transfer/swap transactions for Shield post_tx cohort evaluation
const isPostTxTransaction = [
TransactionType.simpleSend,
TransactionType.tokenMethodTransfer,
TransactionType.swap,
TransactionType.swapAndSend,
].includes(transactionMeta.type);

const { pendingShieldCohort } = this.appStateController.state;
if (isPostTxTransaction && !pendingShieldCohort) {
this.appStateController.setPendingShieldCohort(
COHORT_NAMES.POST_TX,
transactionMeta.type,
);
}
this.subscriptionService.trackSubscriptionRequestEvent(
'completed',
transactionMeta,
{
gas_sponsored: isSponsored,
},
);
} catch (error) {
log.error('Error on Shield subscription approval transaction', error);
this.subscriptionService.trackSubscriptionRequestEvent(
'failed',
transactionMeta,
{
error_message: error.message,
},
);
throw error;
}
}

/**
* @deprecated
* Controllers should subscribe to messenger events internally rather than relying on the client.
Expand Down
Loading
Loading