Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
7b6ad10
feat: added shield plan UI
lionellbriones Aug 19, 2025
af2361a
feat: updated font size
lionellbriones Aug 19, 2025
1e12eb8
feat: add save badge, custom token list and confirmation style UI
lionellbriones Aug 21, 2025
9b04558
feat: added locales
lionellbriones Aug 25, 2025
a65959b
feat: fix states
lionellbriones Aug 25, 2025
94de6a5
feat: added shield payment modal tests
lionellbriones Aug 25, 2025
b1682cb
feat: add shield plan test
lionellbriones Aug 25, 2025
24fa9ef
Merge branch 'main' into feat/shield-plan
lionellbriones Aug 27, 2025
9e965cb
feat: filter stable coins
lionellbriones Aug 28, 2025
2f2c0f1
Merge branch 'main' into feat/shield-plan
lionellbriones Aug 28, 2025
e11a3cd
Merge branch 'main' into feat/shield-plan
lionellbriones Aug 28, 2025
8dfd009
feat: fix lint and unit tests
lionellbriones Aug 28, 2025
357b5e1
feat: fix lint and null selected asset
lionellbriones Aug 28, 2025
38b7f25
fix: test lint
lionellbriones Aug 28, 2025
c12c694
fix: removed unused codes
lionellbriones Aug 28, 2025
3cc3139
fix: issue on token list generator
lionellbriones Aug 28, 2025
c986aea
feat: update code owner
lionellbriones Aug 29, 2025
d991948
feat: remove code owners
lionellbriones Sep 2, 2025
7f29c2a
Merge branch 'main' into feat/shield-plan
lionellbriones Sep 11, 2025
4fcb2e8
feat: fix messages lint
lionellbriones Sep 11, 2025
6d196b4
feat: add loader
lionellbriones Sep 12, 2025
0446205
feat: subscription controller init
tuna1207 Sep 11, 2025
4e205ce
feat: expose subscription api
tuna1207 Sep 11, 2025
8729e79
feat: handle shield payment plan tokens
tuna1207 Sep 13, 2025
303655b
fix: correct pricing hook
tuna1207 Sep 15, 2025
a5a5fc4
feat: update actions
tuna1207 Sep 15, 2025
da1e06f
feat: shield plan subscription data
tuna1207 Sep 15, 2025
3c7537a
feat: handle controller method
tuna1207 Sep 15, 2025
2ed847d
feat: update shield screen integration
tuna1207 Sep 15, 2025
2a65c8f
feat: update billing display
tuna1207 Sep 16, 2025
2b253ec
feat: update user subscriptions hook
tuna1207 Sep 16, 2025
148a8a6
Merge branch 'main' into feat/shield-plan
lionellbriones Sep 16, 2025
d3a82a7
Merge branch 'feat/shield-plan' into feat/subscription-payment-option…
tuna1207 Sep 16, 2025
212203d
Merge branch 'feat/subscription-payment-options-integration' into fea…
tuna1207 Sep 16, 2025
cb7cab5
feat: move launchwebauthflow to background
tuna1207 Sep 16, 2025
d0a8537
fix: correct trial requested
tuna1207 Sep 16, 2025
e06d286
fix: lowercase address compare
tuna1207 Sep 16, 2025
4989432
fix: typo
tuna1207 Sep 16, 2025
9fca627
fix: correct comment
tuna1207 Sep 16, 2025
4b38166
fix: use selected token icon
tuna1207 Sep 16, 2025
f852d3c
Merge branch 'feat/subscription-payment-options-integration' into fea…
tuna1207 Sep 16, 2025
1169cb4
Merge branch 'main' into feat/subscription-payment-options-integration
tuna1207 Sep 16, 2025
e5b423b
chore: temp controller tgz
tuna1207 Sep 16, 2025
bca6731
fix: lint
tuna1207 Sep 16, 2025
92b4689
fix: test case
tuna1207 Sep 16, 2025
575c04f
fix: correct log import
tuna1207 Sep 16, 2025
19c2dfa
fix: shield plan story
tuna1207 Sep 16, 2025
21a1463
fix: undefined subscriptions
tuna1207 Sep 16, 2025
d527b73
chore: use correct subscription controller version
tuna1207 Sep 16, 2025
90d3bba
fix: lint locale
tuna1207 Sep 17, 2025
7865311
fix: shield plan text
tuna1207 Sep 17, 2025
6af84c9
chore: yarn dedupe
tuna1207 Sep 17, 2025
3bee4f8
Update LavaMoat policies
metamaskbot Sep 17, 2025
a32a047
fix: start subscription with card params
tuna1207 Sep 17, 2025
17f70d6
chore: update lavamoat
tuna1207 Sep 17, 2025
a1ab419
Merge branch 'feat/subscription-payment-options-integration' into fea…
tuna1207 Sep 17, 2025
4f2d9c8
Update LavaMoat policies
metamaskbot Sep 17, 2025
86329d1
Merge branch 'feat/subscription-payment-options-integration' into fea…
tuna1207 Sep 17, 2025
419a170
feat: update e2e state check
tuna1207 Sep 17, 2025
49f15b7
fix: lint
tuna1207 Sep 17, 2025
b42663b
Merge branch 'feat/subscription-payment-options-integration' into fea…
tuna1207 Sep 17, 2025
326f38b
feat: stop showing loader on view billing
lionellbriones Sep 17, 2025
4ce1de3
Merge branch 'main' into feat/subscription-shield-settings-integration
tuna1207 Sep 17, 2025
993e087
feat: use customer id for member ship id
tuna1207 Sep 17, 2025
6f3b9e3
feat: cancel subscription button show and date
tuna1207 Sep 17, 2025
ea10ede
feat: updated locales banner alert and payment method button
lionellbriones Sep 18, 2025
4b3d276
feat: added paused state
lionellbriones Sep 18, 2025
0191870
feat: update locales and copywriting
lionellbriones Sep 18, 2025
2494a64
chore: subscription controller dev build use dev backend
tuna1207 Sep 18, 2025
c8e8808
fix: correct payment method card
tuna1207 Sep 18, 2025
6e609b6
feat: add a loader when user submit shield plan
lionellbriones Sep 18, 2025
3244641
refactor: start subscription pop up loading
tuna1207 Sep 18, 2025
9966e3b
fix: lint
tuna1207 Sep 19, 2025
d083437
fix: correct sheild plan when continue
tuna1207 Sep 19, 2025
ccdb613
fix: correct platform usage
tuna1207 Sep 19, 2025
7e772cd
fix: test cases
tuna1207 Sep 19, 2025
3a2c5ad
fix: trialed param
tuna1207 Sep 22, 2025
7844231
fix: trailed check test
tuna1207 Sep 22, 2025
2339a23
fix: correct start subscription function
tuna1207 Sep 22, 2025
35e8cba
chore: add todo comment
tuna1207 Sep 22, 2025
f5652df
feat: update subscription check out url handling
tuna1207 Sep 22, 2025
490dd55
fix: remove comment
tuna1207 Sep 22, 2025
68e928d
fix: variable name
tuna1207 Sep 22, 2025
3343545
fix: correct subscription fetching
tuna1207 Sep 23, 2025
3792f81
chore: update subscription controller 0.2.0
tuna1207 Sep 24, 2025
b40543e
fix: yarn dedupe
tuna1207 Sep 24, 2025
2f7b8ec
fix: type test
tuna1207 Sep 24, 2025
7604111
Update LavaMoat policies
metamaskbot Sep 24, 2025
44f461f
Merge branch 'main' into feat/checkout-url-handling
tuna1207 Sep 24, 2025
229db31
Merge branch 'main' into feat/checkout-url-handling
chaitanyapotti Sep 24, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 67 additions & 19 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ import { NameControllerInit } from './controller-init/confirmations/name-control
import { GasFeeControllerInit } from './controller-init/confirmations/gas-fee-controller-init';
import { SelectedNetworkControllerInit } from './controller-init/selected-network-controller-init';
import { SubscriptionControllerInit } from './controller-init/subscription';
import { webAuthenticatorFactory } from './services/oauth/web-authenticator-factory';
import { getIdentityAPI } from './services/oauth/web-authenticator-factory';
import { AccountTrackerControllerInit } from './controller-init/account-tracker-controller-init';
import { OnboardingControllerInit } from './controller-init/onboarding-controller-init';
import { RemoteFeatureFlagControllerInit } from './controller-init/remote-feature-flag-controller-init';
Expand Down Expand Up @@ -2219,29 +2219,77 @@ export default class MetamaskController extends EventEmitter {
return publicConfigStore;
}

async startSubscriptionWithCard(params) {
const webAuthenticator = webAuthenticatorFactory();
async startSubscriptionWithCard(
params,
/* current tab can be undefined if open from non tab context (e.g. popup, background) */
currentTabId,
) {
const identityAPI = getIdentityAPI();
const redirectUrl = identityAPI.getRedirectURL();

const { checkoutSessionUrl } =
await this.subscriptionController.startShieldSubscriptionWithCard(params);
// TODO: use chrome.tabs manually to have full browser feature in checkout session (e.g auto-fill form, etc.)
// use same launchWebAuthFlow api as oauth service to launch the stripe checkout session and get redirected back to extension from a pop up
// without having to handle chrome.windows.create and chrome.tabs.onUpdated event explicitly
await this.subscriptionController.startShieldSubscriptionWithCard({
...params,
successUrl: redirectUrl,
});

const checkoutTab = await this.platform.openTab({
url: checkoutSessionUrl,
});

// --- We will define our listeners here so we can reference them for cleanup ---
// eslint-disable-next-line prefer-const
let onTabUpdatedListener;
// eslint-disable-next-line prefer-const
let onTabRemovedListener;

await new Promise((resolve, reject) => {
webAuthenticator.launchWebAuthFlow(
{
url: checkoutSessionUrl,
interactive: true,
},
(responseUrl) => {
try {
resolve(responseUrl);
} catch (error) {
reject(error);
let checkoutSucceeded = false;
const cleanupListeners = () => {
// Important: Remove both listeners to prevent memory leaks
if (onTabUpdatedListener) {
this.platform.removeTabUpdatedListener(onTabUpdatedListener);
}
if (onTabRemovedListener) {
this.platform.removeTabRemovedListener(onTabRemovedListener);
}
};

// Set up a listener to watch for navigation on that specific tab
onTabUpdatedListener = (tabId, changeInfo, _tab) => {
// We only care about updates to our specific checkout tab
if (tabId === checkoutTab.id && changeInfo.url) {
if (changeInfo.url.startsWith(redirectUrl)) {
// Payment was successful!
checkoutSucceeded = true;

// Clean up: close the tab
this.platform.closeTab(tabId);
Copy link

Choose a reason for hiding this comment

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

Bug

The startSubscriptionWithCard method calls this.platform.closeTab(tabId) without awaiting its async operation or handling potential rejections. If closeTab fails to close the tab, the onTabRemovedListener won't trigger, causing the checkout Promise to hang indefinitely and leaving event listeners active.

Fix in Cursor Fix in Web

}
},
);
// TODO: handle cancel url ?
}
};
this.platform.addTabUpdatedListener(onTabUpdatedListener);

// Set up a listener to watch for tab removal
onTabRemovedListener = (tabId) => {
if (tabId === checkoutTab.id) {
cleanupListeners();
if (checkoutSucceeded) {
resolve();
} else {
reject(new Error('Checkout failed'));
}
}
};
this.platform.addTabRemovedListener(onTabRemovedListener);
});

if (!currentTabId) {
// open extension browser shield settings if open from pop up (no current tab)
this.platform.openExtensionInBrowser('/settings/transaction-shield');
}

// fetch latest user subscriptions after checkout
const subscriptions = await this.subscriptionController.getSubscriptions();
return subscriptions;
Expand Down
16 changes: 16 additions & 0 deletions app/scripts/platforms/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ export default class ExtensionPlatform {
browser.windows.onRemoved.addListener(listener);
}

addTabRemovedListener(listener) {
browser.tabs.onRemoved.addListener(listener);
}

removeTabRemovedListener(listener) {
browser.tabs.onRemoved.removeListener(listener);
}

addTabUpdatedListener(listener) {
browser.tabs.onUpdated.addListener(listener);
}

removeTabUpdatedListener(listener) {
browser.tabs.onUpdated.removeListener(listener);
}

async getAllWindows() {
const windows = await browser.windows.getAll();
return windows;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@
"@metamask/solana-wallet-snap": "^2.4.0",
"@metamask/solana-wallet-standard": "^0.5.1",
"@metamask/streams": "^0.4.0",
"@metamask/subscription-controller": "^0.1.0",
"@metamask/subscription-controller": "^0.2.0",
"@metamask/transaction-controller": "^60.2.0",
"@metamask/user-operation-controller": "^39.0.0",
"@metamask/utils": "^11.4.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const mockSubscription: Subscription = {
card: {
brand: 'Visa',
last4: '1234',
displayBrand: 'Visa',
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ describe('Transaction Shield Page', () => {
card: {
brand: 'Visa',
last4: '1234',
displayBrand: 'Visa',
},
},
} satisfies Subscription,
Expand Down
3 changes: 2 additions & 1 deletion ui/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,10 @@ export function startSubscriptionWithCard(params: {
recurringInterval: RecurringInterval;
}): ThunkAction<Subscription[], MetaMaskReduxState, unknown, AnyAction> {
return async (_dispatch: MetaMaskReduxDispatch) => {
const currentTab = await global.platform.currentTab();
const subscriptions = await submitRequestToBackground<Subscription[]>(
'startSubscriptionWithCard',
[params],
[params, currentTab?.id],
);

return subscriptions;
Expand Down
12 changes: 6 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7475,16 +7475,16 @@ __metadata:
languageName: node
linkType: hard

"@metamask/subscription-controller@npm:^0.1.0":
version: 0.1.0
resolution: "@metamask/subscription-controller@npm:0.1.0"
"@metamask/subscription-controller@npm:^0.2.0":
version: 0.2.0
resolution: "@metamask/subscription-controller@npm:0.2.0"
dependencies:
"@metamask/base-controller": "npm:^8.3.0"
"@metamask/base-controller": "npm:^8.4.0"
"@metamask/controller-utils": "npm:^11.14.0"
"@metamask/utils": "npm:^11.8.0"
peerDependencies:
"@metamask/profile-sync-controller": ^25.0.0
checksum: 10/f99dd74b6b057a357676447222f75a3753ce7522e2ff61002de46809bd67bcc3b8d71d246260aae302c3a458fec62ff543b03cf018d89bf77f1734292d24e6ca
checksum: 10/c97a25966f6a4f3670bb096e4b31e5c458705fd8224bbe6bc861104ed03ac775ae4d7d1038c62a31e3327cc079ae0cf1920e64407b868f5e4d147aebb057789b
languageName: node
linkType: hard

Expand Down Expand Up @@ -32003,7 +32003,7 @@ __metadata:
"@metamask/solana-wallet-snap": "npm:^2.4.0"
"@metamask/solana-wallet-standard": "npm:^0.5.1"
"@metamask/streams": "npm:^0.4.0"
"@metamask/subscription-controller": "npm:^0.1.0"
"@metamask/subscription-controller": "npm:^0.2.0"
"@metamask/superstruct": "npm:^3.2.1"
"@metamask/test-bundler": "npm:^1.0.0"
"@metamask/test-dapp": "npm:9.3.0"
Expand Down
Loading