Skip to content

fix: swap tx status events #5993

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4b005fb
fix: emit Submitted event when submitTx is called
micaelae Jun 17, 2025
8bd6462
fix: populate Failed event using activeQuote if submission fails
micaelae Jun 17, 2025
f6358d3
fix: emit solana swap Failed events
micaelae Jun 17, 2025
2280e71
fix: emit solana swap Completed event after submission
micaelae Jun 17, 2025
4e4e22d
fix: set correct tx type for evm swaps
micaelae Jun 17, 2025
af28c10
fix: can_submit event property
micaelae Jun 17, 2025
75d5e28
chore: remove Multichain tx event subscription
micaelae Jun 17, 2025
2e2b75a
fix: unit tests
micaelae Jun 18, 2025
c401c00
chore: update changelog
micaelae Jun 18, 2025
c7d3361
chore: rm multichain-transaction-controller dependency
micaelae Jun 18, 2025
8adfae2
chore: update changelog
micaelae Jun 18, 2025
0ad097a
chore: update yarn.lock
micaelae Jun 18, 2025
c5f520a
chore: update tsconfig
micaelae Jun 18, 2025
d6ff344
Merge branch 'main' into mms2608-fix-swap-metrics
micaelae Jun 18, 2025
3ae959c
Merge branch 'main' into mms2608-fix-swap-metrics
micaelae Jun 18, 2025
db6bf79
chore: update event types
micaelae Jun 18, 2025
97ed68f
Merge branch 'main' into mms2608-fix-swap-metrics
micaelae Jun 19, 2025
7bee9fb
chore: add more unit tests
micaelae Jun 19, 2025
df5f2da
chore: getEVMSwapTxPropertiesFromTransactionMeta util
micaelae Jun 19, 2025
51ab1b9
chore: update tx event properties
micaelae Jun 19, 2025
206d8ec
fix: rm missing type
micaelae Jun 19, 2025
ece2113
test: update solana unit tests
micaelae Jun 19, 2025
65270a2
test: solana bridge txs
micaelae Jun 19, 2025
98c0705
test: solana swaps
micaelae Jun 19, 2025
d1aaaef
test: evm bridge
micaelae Jun 19, 2025
e2f4a4d
test: define call mock within suites
micaelae Jun 19, 2025
b5423ad
test: evm swaps
micaelae Jun 19, 2025
c6adbf1
fix: rm missing type
micaelae Jun 19, 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
5 changes: 5 additions & 0 deletions packages/bridge-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Set correct `can_submit` property on Unified SwapBridge events ([#5993](https://github.com/MetaMask/core/pull/5993))
- Use activeQuote to populate default properties for Submitted and Failed events, if tx fails before being confirmed on chain ([#5993](https://github.com/MetaMask/core/pull/5993))

## [33.0.0]

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,22 @@ Array [
"actual_time_minutes": 10,
"allowance_reset_transaction": "PENDING",
"approval_transaction": "PENDING",
"can_submit": true,
"chain_id_destination": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"chain_id_source": "eip155:1",
"custom_slippage": true,
"destination_transaction": "PENDING",
"error_message": "error_message",
"gas_included": false,
"initial_load_time_all_quotes": 0,
"is_hardware_wallet": false,
"price_impact": 0,
"provider": "provider_bridge",
"quoted_time_minutes": 0,
"quotes_count": 0,
"quotes_list": Array [],
"security_warnings": Array [],
"slippage_limit": undefined,
"source_transaction": "PENDING",
"stx_enabled": false,
"swap_type": "crosschain",
Expand All @@ -122,6 +127,43 @@ Array [
]
`;

exports[`BridgeController trackUnifiedSwapBridgeEvent bridge-status-controller calls should track the Failed event before tx is submitted 1`] = `
Array [
Array [
"Unified SwapBridge Failed",
Object {
"action_type": "crosschain-v1",
"can_submit": true,
"chain_id_destination": "eip155:1",
"chain_id_source": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"custom_slippage": true,
"error_message": "Failed to submit tx",
"gas_included": false,
"initial_load_time_all_quotes": 0,
"is_hardware_wallet": false,
"price_impact": 12,
"provider": "provider_bridge",
"quoted_time_minutes": 2,
"quotes_count": 2,
"quotes_list": Array [
"lifi_mayan",
"lifi_mayanMCTP",
],
"slippage_limit": 0.5,
"stx_enabled": false,
"swap_type": "crosschain",
"token_address_destination": "eip155:1/erc20:0x1234",
"token_address_source": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:NATIVE",
"token_symbol_destination": "USDC",
"token_symbol_source": "ETH",
"usd_amount_source": 100,
"usd_quoted_gas": 1,
"usd_quoted_return": 113,
},
],
]
`;

exports[`BridgeController trackUnifiedSwapBridgeEvent bridge-status-controller calls should track the SnapConfirmationViewed event 1`] = `
Array [
Array [
Expand Down Expand Up @@ -153,24 +195,31 @@ Array [
"Unified SwapBridge Submitted",
Object {
"action_type": "crosschain-v1",
"can_submit": true,
"chain_id_destination": "eip155:10",
"chain_id_source": "eip155:1",
"chain_id_source": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"custom_slippage": true,
"gas_included": false,
"initial_load_time_all_quotes": 0,
"is_hardware_wallet": false,
"price_impact": 0,
"price_impact": 12,
"provider": "provider_bridge",
"quoted_time_minutes": 0,
"security_warnings": Array [],
"quoted_time_minutes": 2,
"quotes_count": 2,
"quotes_list": Array [
"lifi_mayan",
"lifi_mayanMCTP",
],
"slippage_limit": 0.5,
"stx_enabled": false,
"swap_type": "crosschain",
"token_address_destination": "eip155:10/slip44:60",
"token_address_source": "eip155:1/slip44:60",
"token_address_destination": "eip155:10/erc20:0x1234",
"token_address_source": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:NATIVE",
"token_symbol_destination": "USDC",
"token_symbol_source": "ETH",
"usd_amount_source": 100,
"usd_quoted_gas": 0,
"usd_quoted_return": 0,
"usd_quoted_gas": 1,
"usd_quoted_return": 113,
},
],
]
Expand All @@ -182,7 +231,7 @@ Array [
"Unified SwapBridge All Quotes Opened",
Object {
"action_type": "crosschain-v1",
"can_submit": false,
"can_submit": true,
"chain_id_destination": null,
"chain_id_source": "eip155:1",
"custom_slippage": false,
Expand Down Expand Up @@ -211,7 +260,7 @@ Array [
Object {
"action_type": "crosschain-v1",
"best_quote_provider": "provider_bridge2",
"can_submit": false,
"can_submit": true,
"chain_id_destination": null,
"chain_id_source": "eip155:1",
"custom_slippage": false,
Expand Down Expand Up @@ -295,7 +344,7 @@ Array [
Object {
"action_type": "crosschain-v1",
"best_quote_provider": "provider_bridge2",
"can_submit": false,
"can_submit": true,
"chain_id_destination": null,
"chain_id_source": "eip155:1",
"custom_slippage": false,
Expand Down Expand Up @@ -326,7 +375,7 @@ Array [
Object {
"action_type": "crosschain-v1",
"best_quote_provider": "provider_bridge2",
"can_submit": false,
"can_submit": true,
"chain_id_destination": null,
"chain_id_source": "eip155:1",
"custom_slippage": false,
Expand Down Expand Up @@ -413,7 +462,7 @@ Array [
Object {
"action_type": "crosschain-v1",
"best_quote_provider": "provider_bridge2",
"can_submit": true,
"can_submit": false,
"chain_id_destination": "eip155:10",
"chain_id_source": "eip155:1",
"custom_slippage": true,
Expand Down
85 changes: 68 additions & 17 deletions packages/bridge-controller/src/bridge-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1761,28 +1761,38 @@ describe('BridgeController', function () {
});

it('should track the Submitted event', () => {
bridgeController.trackUnifiedSwapBridgeEvent(
const controller = new BridgeController({
messenger: messengerMock,
getLayer1GasFee: getLayer1GasFeeMock,
clientId: BridgeClientId.EXTENSION,
fetchFn: mockFetchFn,
trackMetaMetricsFn,
state: {
quoteRequest: {
srcChainId: SolScope.Mainnet,
destChainId: '0xa',
srcTokenAddress: 'NATIVE',
destTokenAddress: '0x1234',
srcTokenAmount: '1000000',
walletAddress: '0x123',
slippage: 0.5,
},
quotes: mockBridgeQuotesSolErc20 as never,
},
});
controller.trackUnifiedSwapBridgeEvent(
UnifiedSwapBridgeEventName.Submitted,
{
provider: 'provider_bridge',
usd_quoted_gas: 0,
usd_quoted_gas: 1,
gas_included: false,
quoted_time_minutes: 0,
usd_quoted_return: 0,
price_impact: 0,
chain_id_source: formatChainIdToCaip(1),
quoted_time_minutes: 2,
usd_quoted_return: 113,
provider: 'provider_bridge',
price_impact: 12,
token_symbol_source: 'ETH',
token_address_source: getNativeAssetForChainId(1).assetId,
custom_slippage: true,
usd_amount_source: 100,
stx_enabled: false,
is_hardware_wallet: false,
swap_type: MetricsSwapType.CROSSCHAIN,
action_type: MetricsActionType.CROSSCHAIN_V1,
chain_id_destination: formatChainIdToCaip(10),
token_symbol_destination: 'USDC',
token_address_destination: getNativeAssetForChainId(10).assetId,
security_warnings: [],
stx_enabled: false,
usd_amount_source: 100,
},
);
expect(trackMetaMetricsFn).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -1864,6 +1874,47 @@ describe('BridgeController', function () {

expect(trackMetaMetricsFn.mock.calls).toMatchSnapshot();
});

it('should track the Failed event before tx is submitted', () => {
const controller = new BridgeController({
messenger: messengerMock,
getLayer1GasFee: getLayer1GasFeeMock,
clientId: BridgeClientId.EXTENSION,
fetchFn: mockFetchFn,
trackMetaMetricsFn,
state: {
quoteRequest: {
srcChainId: SolScope.Mainnet,
destChainId: '1',
srcTokenAddress: 'NATIVE',
destTokenAddress: '0x1234',
srcTokenAmount: '1000000',
walletAddress: '0x123',
slippage: 0.5,
},
quotes: mockBridgeQuotesSolErc20 as never,
},
});
controller.trackUnifiedSwapBridgeEvent(
UnifiedSwapBridgeEventName.Failed,
{
error_message: 'Failed to submit tx',
usd_quoted_gas: 1,
gas_included: false,
quoted_time_minutes: 2,
usd_quoted_return: 113,
provider: 'provider_bridge',
price_impact: 12,
token_symbol_source: 'ETH',
token_symbol_destination: 'USDC',
stx_enabled: false,
usd_amount_source: 100,
},
);
expect(trackMetaMetricsFn).toHaveBeenCalledTimes(1);

expect(trackMetaMetricsFn.mock.calls).toMatchSnapshot();
});
});

describe('trackUnifiedSwapBridgeEvent client-side call exceptions', () => {
Expand Down
15 changes: 12 additions & 3 deletions packages/bridge-controller/src/bridge-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ export class BridgeController extends StaticIntervalPollingController<BridgePoll
'best_quote_provider' | 'price_impact'
> => {
return {
can_submit: Boolean(this.state.quoteRequest.insufficientBal), // TODO check if balance is sufficient for network fees
can_submit: !this.state.quoteRequest.insufficientBal, // TODO check if balance is sufficient for network fees
quotes_count: this.state.quotes.length,
quotes_list: this.state.quotes.map(({ quote }) =>
formatProviderLabel(quote),
Expand Down Expand Up @@ -825,10 +825,19 @@ export class BridgeController extends StaticIntervalPollingController<BridgePoll
...this.#getRequestParams(),
...this.#getRequestMetadata(),
};
// These are populated by BridgeStatusController
case UnifiedSwapBridgeEventName.Submitted:
case UnifiedSwapBridgeEventName.Failed: {
// Populate the properties that the error occurred before the tx was submitted
return {
...baseProperties,
...this.#getRequestParams(),
...this.#getRequestMetadata(),
...this.#getQuoteFetchData(),
...propertiesFromClient,
};
}
// These are populated by BridgeStatusController
case UnifiedSwapBridgeEventName.Completed:
case UnifiedSwapBridgeEventName.Failed:
return propertiesFromClient;
case UnifiedSwapBridgeEventName.InputChanged:
default:
Expand Down
3 changes: 3 additions & 0 deletions packages/bridge-controller/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export {

export { SWAPS_API_V2_BASE_URL } from './constants/swaps';

export { MetricsActionType, MetricsSwapType } from './utils/metrics/constants';

export {
getEthUsdtResetData,
isEthUsdt,
Expand All @@ -117,6 +119,7 @@ export {
formatChainIdToCaip,
formatChainIdToHex,
formatAddressToCaipReference,
formatAddressToAssetId,
} from './utils/caip-formatters';

export {
Expand Down
2 changes: 2 additions & 0 deletions packages/bridge-controller/src/utils/feature-flags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ describe('feature-flags', () => {
'1151111081099710': {
isActiveSrc: true,
isActiveDest: true,
isSnapConfirmationEnabled: false,
},
},
};
Expand Down Expand Up @@ -79,6 +80,7 @@ describe('feature-flags', () => {
'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': {
isActiveSrc: true,
isActiveDest: true,
isSnapConfirmationEnabled: false,
},
},
});
Expand Down
Loading
Loading