Skip to content
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

chore: set bridge src network, tokens and top assets #26214

Merged
merged 5 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions app/scripts/constants/sentry-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ export const SENTRY_BACKGROUND_STATE = {
},
destTokens: {},
destTopAssets: [],
srcTokens: {},
srcTopAssets: [],
},
},
CronjobController: {
Expand Down
24 changes: 24 additions & 0 deletions app/scripts/controllers/bridge/bridge-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,28 @@ describe('BridgeController', function () {
{ address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984', symbol: 'ABC' },
]);
});

it('selectSrcNetwork should set the bridge src tokens and top assets', async function () {
await bridgeController.selectSrcNetwork('0xa');
expect(bridgeController.state.bridgeState.srcTokens).toStrictEqual({
'0x0000000000000000000000000000000000000000': {
address: '0x0000000000000000000000000000000000000000',
decimals: 18,
iconUrl: './images/eth_logo.svg',
name: 'Ether',
symbol: 'ETH',
},
'0x1f9840a85d5af5bf1d1762f925bdaddc4201f984': {
address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
symbol: 'ABC',
decimals: 16,
},
});
expect(bridgeController.state.bridgeState.srcTopAssets).toStrictEqual([
{
address: '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984',
symbol: 'ABC',
},
]);
});
});
9 changes: 9 additions & 0 deletions app/scripts/controllers/bridge/bridge-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export default class BridgeController extends BaseController<
`${BRIDGE_CONTROLLER_NAME}:setBridgeFeatureFlags`,
this.setBridgeFeatureFlags.bind(this),
);
this.messagingSystem.registerActionHandler(
`${BRIDGE_CONTROLLER_NAME}:selectSrcNetwork`,
this.selectSrcNetwork.bind(this),
);
this.messagingSystem.registerActionHandler(
`${BRIDGE_CONTROLLER_NAME}:selectDestNetwork`,
this.selectDestNetwork.bind(this),
Expand All @@ -61,6 +65,11 @@ export default class BridgeController extends BaseController<
});
};

selectSrcNetwork = async (chainId: Hex) => {
await this.#setTopAssets(chainId, 'srcTopAssets');
await this.#setTokens(chainId, 'srcTokens');
};

selectDestNetwork = async (chainId: Hex) => {
await this.#setTopAssets(chainId, 'destTopAssets');
await this.#setTokens(chainId, 'destTokens');
Expand Down
2 changes: 2 additions & 0 deletions app/scripts/controllers/bridge/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const DEFAULT_BRIDGE_CONTROLLER_STATE: BridgeControllerState = {
[BridgeFeatureFlagsKey.NETWORK_SRC_ALLOWLIST]: [],
[BridgeFeatureFlagsKey.NETWORK_DEST_ALLOWLIST]: [],
},
srcTokens: {},
srcTopAssets: [],
destTokens: {},
destTopAssets: [],
};
4 changes: 4 additions & 0 deletions app/scripts/controllers/bridge/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ export type BridgeFeatureFlags = {

export type BridgeControllerState = {
bridgeFeatureFlags: BridgeFeatureFlags;
srcTokens: Record<string, SwapsTokenObject>;
srcTopAssets: { address: string }[];
destTokens: Record<string, SwapsTokenObject>;
destTopAssets: { address: string }[];
};

export enum BridgeUserAction {
SELECT_SRC_NETWORK = 'selectSrcNetwork',
SELECT_DEST_NETWORK = 'selectDestNetwork',
}
export enum BridgeBackgroundAction {
Expand All @@ -40,6 +43,7 @@ type BridgeControllerAction<FunctionName extends keyof BridgeController> = {
// Maps to BridgeController function names
type BridgeControllerActions =
| BridgeControllerAction<BridgeBackgroundAction.SET_FEATURE_FLAGS>
| BridgeControllerAction<BridgeUserAction.SELECT_SRC_NETWORK>
| BridgeControllerAction<BridgeUserAction.SELECT_DEST_NETWORK>;

type BridgeControllerEvents = ControllerStateChangeEvent<
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/metamask-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3891,6 +3891,10 @@ export default class MetamaskController extends EventEmitter {
this.controllerMessenger,
`${BRIDGE_CONTROLLER_NAME}:${BridgeBackgroundAction.SET_FEATURE_FLAGS}`,
),
[BridgeUserAction.SELECT_SRC_NETWORK]: this.controllerMessenger.call.bind(
this.controllerMessenger,
`${BRIDGE_CONTROLLER_NAME}:${BridgeUserAction.SELECT_SRC_NETWORK}`,
),
[BridgeUserAction.SELECT_DEST_NETWORK]:
this.controllerMessenger.call.bind(
this.controllerMessenger,
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/default-fixture.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ function defaultFixture(inputChainId = CHAIN_IDS.LOCALHOST) {
},
destTokens: {},
destTopAssets: [],
srcTokens: {},
srcTopAssets: [],
},
},
CurrencyController: {
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/fixture-builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ class FixtureBuilder {
},
destTokens: {},
destTopAssets: [],
srcTokens: {},
srcTopAssets: [],
},
};
return this;
Expand Down
12 changes: 11 additions & 1 deletion test/e2e/tests/bridge/bridge-test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,17 @@ const mockServer =
};
}),
);
return Promise.all(featureFlagMocks);
const portfolioMock = async () =>
await mockServer_
.forGet('https://portfolio.metamask.io/bridge')
.always()
.thenCallback(() => {
return {
statusCode: 200,
json: {},
};
});
return Promise.all([...featureFlagMocks, portfolioMock]);
};

export const getBridgeFixtures = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@
"destNetworkAllowlist": { "0": "string", "1": "string", "2": "string" }
},
"destTokens": {},
"destTopAssets": {}
"destTopAssets": {},
"srcTokens": {},
"srcTopAssets": {}
}
},
"CronjobController": { "jobs": "object" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,9 @@
"destNetworkAllowlist": { "0": "string", "1": "string", "2": "string" }
},
"destTokens": {},
"destTopAssets": {}
"destTopAssets": {},
"srcTokens": {},
"srcTopAssets": {}
},
"ensEntries": "object",
"ensResolutionsByAddress": "object",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@
}
},
"destTokens": {},
"destTopAssets": {}
"destTopAssets": {},
"srcTokens": {},
"srcTopAssets": {}
}
},
"SubjectMetadataController": { "subjectMetadata": "object" },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@
}
},
"destTokens": {},
"destTopAssets": {}
"destTopAssets": {},
"srcTokens": {},
"srcTopAssets": {}
}
},
"TransactionController": { "transactions": "object" },
Expand Down
10 changes: 10 additions & 0 deletions ui/ducks/bridge/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ export const setBridgeFeatureFlags = () => {
};

// User actions
export const setFromChain = (chainId: Hex) => {
return async (dispatch: MetaMaskReduxDispatch) => {
dispatch(
callBridgeControllerMethod<Hex>(BridgeUserAction.SELECT_SRC_NETWORK, [
chainId,
]),
);
};
};

export const setToChain = (chainId: Hex) => {
return async (dispatch: MetaMaskReduxDispatch) => {
dispatch(setToChainId_(chainId));
Expand Down
18 changes: 18 additions & 0 deletions ui/ducks/bridge/bridge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
setFromTokenInputValue,
setToChain,
setToToken,
setFromChain,
} from './actions';

const middleware = [thunk];
Expand Down Expand Up @@ -100,4 +101,21 @@ describe('Ducks - Bridge', () => {
expect(mockSetBridgeFeatureFlags).toHaveBeenCalledTimes(1);
});
});

describe('setFromChain', () => {
it('calls the selectSrcNetwork background action', async () => {
const mockSelectSrcNetwork = jest.fn().mockReturnValue({});
setBackgroundConnection({
[BridgeUserAction.SELECT_SRC_NETWORK]: mockSelectSrcNetwork,
} as never);

await store.dispatch(setFromChain(CHAIN_IDS.MAINNET) as never);

expect(mockSelectSrcNetwork).toHaveBeenCalledTimes(1);
expect(mockSelectSrcNetwork).toHaveBeenCalledWith(
'0x1',
expect.anything(),
);
});
});
});
35 changes: 35 additions & 0 deletions ui/ducks/bridge/selectors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
getFromChain,
getFromChains,
getFromToken,
getFromTokens,
getFromTopAssets,
getIsBridgeTx,
getToAmount,
getToChain,
Expand Down Expand Up @@ -456,4 +458,37 @@ describe('Bridge selectors', () => {
expect(result).toStrictEqual([]);
});
});

describe('getFromTokens', () => {
it('returns src tokens from controller state', () => {
const state = createBridgeMockStore(
{},
{ toChainId: '0x1' },
{
srcTokens: { '0x00': { address: '0x00', symbol: 'TEST' } },
},
);
const result = getFromTokens(state as never);

expect(result).toStrictEqual({
'0x00': { address: '0x00', symbol: 'TEST' },
});
});
});

describe('getFromTopAssets', () => {
it('returns src top assets from controller state', () => {
const state = createBridgeMockStore(
{},
{ toChainId: '0x1' },
{
srcTokens: { '0x00': { address: '0x00', symbol: 'TEST' } },
srcTopAssets: [{ address: '0x00', symbol: 'TEST' }],
},
);
const result = getFromTopAssets(state as never);

expect(result).toStrictEqual([{ address: '0x00', symbol: 'TEST' }]);
});
});
});
8 changes: 8 additions & 0 deletions ui/ducks/bridge/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@ export const getToChain = createDeepEqualSelector(
toChains.find(({ chainId }) => chainId === toChainId),
);

export const getFromTokens = (state: BridgeAppState) => {
return state.metamask.bridgeState.srcTokens ?? {};
};

export const getFromTopAssets = (state: BridgeAppState) => {
return state.metamask.bridgeState.srcTopAssets ?? [];
};

export const getToTopAssets = (state: BridgeAppState) => {
return state.bridge.toChainId ? state.metamask.bridgeState.destTopAssets : [];
};
Expand Down
12 changes: 11 additions & 1 deletion ui/hooks/bridge/useBridging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,16 @@ jest.mock('react-router-dom', () => ({
}),
}));

const mockDispatch = jest.fn().mockReturnValue(() => jest.fn());
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: jest.fn().mockReturnValue(() => jest.fn()),
useDispatch: () => mockDispatch,
}));

const mockSetFromChain = jest.fn();
jest.mock('../../ducks/bridge/actions', () => ({
...jest.requireActual('../../ducks/bridge/actions'),
setFromChain: () => mockSetFromChain(),
}));

const MOCK_METAMETRICS_ID = '0xtestMetaMetricsId';
Expand Down Expand Up @@ -94,6 +101,8 @@ describe('useBridging', () => {
},
});

expect(mockDispatch.mock.calls).toHaveLength(1);

expect(nock(BRIDGE_API_BASE_URL).isDone()).toBe(true);
result.current.openBridgeExperience(location, token, urlSuffix);

Expand Down Expand Up @@ -165,6 +174,7 @@ describe('useBridging', () => {

result.current.openBridgeExperience(location, token, urlSuffix);

expect(mockDispatch.mock.calls).toHaveLength(3);
expect(mockHistoryPush.mock.calls).toHaveLength(1);
expect(mockHistoryPush).toHaveBeenCalledWith(expectedUrl);
expect(openTabSpy).not.toHaveBeenCalled();
Expand Down
Loading
Loading