Skip to content

Commit 80c01eb

Browse files
authored
Feat/multichained smart transactions (#498)
* feat: multichain smart transaction status * fix: refacto * fix: fix build * fix: fix PR comments
1 parent acfb4bb commit 80c01eb

File tree

2 files changed

+217
-44
lines changed

2 files changed

+217
-44
lines changed

src/SmartTransactionsController.test.ts

Lines changed: 116 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,21 @@ describe('SmartTransactionsController', () => {
437437
},
438438
);
439439
});
440+
441+
it('calls updateSmartTransactions if there is a timeoutHandle and pending transactions', async () => {
442+
await withController(({ controller }) => {
443+
const updateSmartTransactionsSpy = jest.spyOn(
444+
controller,
445+
'updateSmartTransactions',
446+
);
447+
448+
controller.timeoutHandle = setTimeout(() => ({}));
449+
450+
controller.poll(1000);
451+
452+
expect(updateSmartTransactionsSpy).toHaveBeenCalled();
453+
});
454+
});
440455
});
441456

442457
describe('updateSmartTransactions', () => {
@@ -725,9 +740,12 @@ describe('SmartTransactionsController', () => {
725740
.get(`/networks/${ethereumChainIdDec}/batchStatus?uuids=uuid1`)
726741
.reply(200, pendingBatchStatusApiResponse);
727742

728-
await controller.fetchSmartTransactionsStatus(uuids, {
729-
networkClientId: NetworkType.mainnet,
730-
});
743+
const params = uuids.map((uuid) => ({
744+
uuid,
745+
chainId: ChainId.mainnet,
746+
}));
747+
748+
await controller.fetchSmartTransactionsStatus(params);
731749

732750
const pendingState = createStateAfterPending()[0];
733751
const pendingTransaction = { ...pendingState, history: [pendingState] };
@@ -786,9 +804,12 @@ describe('SmartTransactionsController', () => {
786804
.get(`/networks/${ethereumChainIdDec}/batchStatus?uuids=uuid2`)
787805
.reply(200, successBatchStatusApiResponse);
788806

789-
await controller.fetchSmartTransactionsStatus(uuids, {
790-
networkClientId: NetworkType.mainnet,
791-
});
807+
const params = uuids.map((uuid) => ({
808+
uuid,
809+
chainId: ChainId.mainnet,
810+
}));
811+
812+
await controller.fetchSmartTransactionsStatus(params);
792813

793814
const [successState] = createStateAfterSuccess();
794815
const successTransaction = {
@@ -1601,9 +1622,12 @@ describe('SmartTransactionsController', () => {
16011622
},
16021623
},
16031624
async ({ controller }) => {
1604-
const handleFetchSpy = jest.spyOn(utils, 'handleFetch');
1625+
const handleFetchSpy = jest
1626+
.spyOn(utils, 'handleFetch')
1627+
.mockImplementation(async () => Promise.resolve({}));
1628+
16051629
const mainnetPollingToken = controller.startPolling({
1606-
networkClientId: NetworkType.mainnet,
1630+
chainIds: [ChainId.mainnet],
16071631
});
16081632

16091633
await advanceTime({ clock, duration: 0 });
@@ -1633,7 +1657,7 @@ describe('SmartTransactionsController', () => {
16331657
fetchHeaders,
16341658
);
16351659

1636-
controller.startPolling({ networkClientId: NetworkType.sepolia });
1660+
controller.startPolling({ chainIds: [ChainId.sepolia] });
16371661
await advanceTime({ clock, duration: 0 });
16381662

16391663
expect(handleFetchSpy).toHaveBeenNthCalledWith(
@@ -1681,6 +1705,57 @@ describe('SmartTransactionsController', () => {
16811705
},
16821706
);
16831707
});
1708+
1709+
it('does not poll for chains that are not supported', async () => {
1710+
// mock this to a noop because it causes an extra fetch call to the API upon state changes
1711+
jest
1712+
.spyOn(SmartTransactionsController.prototype, 'checkPoll')
1713+
.mockImplementation(() => undefined);
1714+
await withController(
1715+
{
1716+
options: {
1717+
// pending transactions in state are required to test polling
1718+
state: {
1719+
smartTransactionsState: {
1720+
...getDefaultSmartTransactionsControllerState()
1721+
.smartTransactionsState,
1722+
smartTransactions: {
1723+
[ChainId.mainnet]: [
1724+
{
1725+
uuid: 'uuid1',
1726+
status: 'pending',
1727+
cancellable: true,
1728+
chainId: ChainId.mainnet,
1729+
},
1730+
],
1731+
[ChainId.sepolia]: [
1732+
{
1733+
uuid: 'uuid2',
1734+
status: 'pending',
1735+
cancellable: true,
1736+
chainId: ChainId.sepolia,
1737+
},
1738+
],
1739+
},
1740+
},
1741+
},
1742+
},
1743+
},
1744+
async ({ controller }) => {
1745+
const handleFetchSpy = jest
1746+
.spyOn(utils, 'handleFetch')
1747+
.mockImplementation(async () => Promise.resolve({}));
1748+
1749+
controller.startPolling({
1750+
chainIds: ['notSupportedChainId' as Hex],
1751+
});
1752+
1753+
await advanceTime({ clock, duration: 0 });
1754+
1755+
expect(handleFetchSpy).not.toHaveBeenCalled();
1756+
},
1757+
);
1758+
});
16841759
});
16851760

16861761
describe('wipeSmartTransactions', () => {
@@ -1984,6 +2059,38 @@ async function withController<ReturnValue>(
19842059
'NetworkController:getState',
19852060
jest.fn().mockReturnValue({
19862061
selectedNetworkClientId: NetworkType.mainnet,
2062+
networkConfigurationsByChainId: {
2063+
'0x1': {
2064+
blockExplorerUrls: ['https://etherscan.io'],
2065+
chainId: '0x1',
2066+
defaultBlockExplorerUrlIndex: 0,
2067+
defaultRpcEndpointIndex: 0,
2068+
name: 'Ethereum Mainnet',
2069+
nativeCurrency: 'ETH',
2070+
rpcEndpoints: [
2071+
{
2072+
networkClientId: NetworkType.mainnet,
2073+
type: 'infura',
2074+
url: 'https://mainnet.infura.io/v3/{infuraProjectId}',
2075+
},
2076+
],
2077+
},
2078+
'0xaa36a7': {
2079+
blockExplorerUrls: ['https://sepolia.etherscan.io'],
2080+
chainId: '0xaa36a7',
2081+
defaultBlockExplorerUrlIndex: 0,
2082+
defaultRpcEndpointIndex: 0,
2083+
name: 'Sepolia',
2084+
nativeCurrency: 'SepoliaETH',
2085+
rpcEndpoints: [
2086+
{
2087+
networkClientId: NetworkType.sepolia,
2088+
type: 'infura',
2089+
url: 'https://sepolia.infura.io/v3/{infuraProjectId}',
2090+
},
2091+
],
2092+
},
2093+
},
19872094
}),
19882095
);
19892096

0 commit comments

Comments
 (0)