Skip to content

Commit

Permalink
fix: indexdb self resetting FE-605 (#1646)
Browse files Browse the repository at this point in the history
- Remove manual reload of wallet.
- Fixed IndexDB [randomly rejecting
TXs](dexie/Dexie.js#613) and or [failing to
open](dexie/Dexie.js#543)
- Fixes error where Dexie would allow insertion of entries with
duplicate primary keys/ids.
- Upgrade Dexie to V4
  • Loading branch information
arthurgeron authored Nov 14, 2024
1 parent 5ebfc5a commit 8c9edd3
Show file tree
Hide file tree
Showing 18 changed files with 708 additions and 1,658 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-goats-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fuels-wallet": patch
---

Fixed IndexDB randomly rejecting TXs and or failing to open
5 changes: 5 additions & 0 deletions .changeset/khaki-walls-juggle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fuels-wallet": patch
---

Remove manual reload of wallet on integrity check fail
8 changes: 8 additions & 0 deletions .changeset/sixty-carpets-share.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@fuels/playwright-utils": patch
"@fuel-wallet/connections": patch
"@fuel-wallet/types": patch
"fuels-wallet": patch
---

Upgrade Dexie to V4
5 changes: 5 additions & 0 deletions .changeset/thirty-moles-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fuels-wallet": patch
---

Fixed error where Dexie would allow insertion of entries with duplicate primary keys/ids.
2 changes: 1 addition & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"compare-versions": "6.1.0",
"cross-fetch": "4.0.0",
"dayjs": "1.11.10",
"dexie": "3.2.7",
"dexie": "4.0.9",
"dexie-observable": "4.0.1-beta.13",
"events": "3.3.0",
"fake-indexeddb": "4.0.2",
Expand Down
31 changes: 25 additions & 6 deletions packages/app/playwright/crx/crx.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,20 @@ test.describe('FuelWallet Extension', () => {
// we need to reconnect the accounts to continue the tests
await connectAccounts();
});
await test.step('wait for initial connection', async () => {
await expect
.poll(
async () => {
return blankPage.evaluate(async () => {
return window.fuel.isConnected();
});
},
{ timeout: 5000 }
)
.toBeTruthy();
});

await test.step('window.fuel.on("connection")', async () => {
await test.step('window.fuel.on("connection") disconnection', async () => {
const onDeleteConnection = blankPage.evaluate(() => {
return new Promise((resolve) => {
window.fuel.on(window.fuel.events.connection, (isConnected) => {
Expand Down Expand Up @@ -677,7 +689,15 @@ test.describe('FuelWallet Extension', () => {
});

// Approve transaction
await hasText(approveTransactionPage, /0\.0000001.ETH/i);
await expect
.poll(
() =>
hasText(approveTransactionPage, /0\.0000001.ETH/i)
.then(() => true)
.catch(() => false),
{ timeout: 15000 }
)
.toBeTruthy();
await waitAriaLabel(
approveTransactionPage,
senderAccount.address.toString()
Expand Down Expand Up @@ -855,20 +875,19 @@ test.describe('FuelWallet Extension', () => {
// delay to avoid the page to listen the event from above swithAccount wrong event
await delay(1000);

const onChangeAccountPromise = blankPage.evaluate(() => {
// Watch for result
const currentAccountEventResult = blankPage.evaluate(() => {
return new Promise((resolve) => {
window.fuel.on(window.fuel.events.currentAccount, (account) => {
resolve(account);
});
});
});

// Switch to account 1
const currentAccount = await switchAccount(popupPage, 'Account 1');

// Check result
const currentAccountEventResult = await onChangeAccountPromise;
expect(currentAccountEventResult).toEqual(currentAccount.address);
expect(await currentAccountEventResult).toEqual(currentAccount.address);
});

await test.step('window.fuel.on("currentAccount") should be null when not connected', async () => {
Expand Down
22 changes: 13 additions & 9 deletions packages/app/playwright/crx/utils/popup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Page } from '@playwright/test';

import { expect } from '@fuels/playwright-utils';
import { getByAriaLabel, hasText, visit, waitAriaLabel } from '../../commons';
import type { MockData } from '../../mocks';

Expand Down Expand Up @@ -27,17 +28,20 @@ export async function switchAccount(popupPage: Page, name: string) {

await getByAriaLabel(popupPage, 'Accounts').click();

await popupPage.waitForTimeout(5000);
await hasText(popupPage, name);
// Add position to click on the element and not on copy button
await getByAriaLabel(popupPage, name).click({
position: {
x: 10,
y: 10,
},
});
await popupPage.waitForTimeout(2000);
await waitAriaLabel(popupPage, `${name} selected`);
await popupPage.waitForTimeout(5000);
await getByAriaLabel(popupPage, name).click();

await expect
.poll(
() =>
waitAriaLabel(popupPage, `${name} selected`)
.then(() => true)
.catch(() => false),
{ timeout: 30000 }
)
.toBeTruthy();

// Return account to be used on tests
account = await getAccountByName(popupPage, name);
Expand Down
14 changes: 7 additions & 7 deletions packages/app/playwright/e2e/ReportError.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ test.describe('ReportError', () => {
});
}

test.beforeEach(async () => {
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
});
});

test('should show Error page when there is a unhandled js error in React', async () => {
await visit(page, '/');
await page.evaluate(() => {
Expand All @@ -50,7 +56,6 @@ test.describe('ReportError', () => {
test('should show Review Error in menu when there is a error in the database', async () => {
await visit(page, '/');
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
await window.fuelDB.errors.add({
id: '12345',
error: {
Expand All @@ -77,7 +82,6 @@ test.describe('ReportError', () => {
test('should be able to ignore a error', async () => {
await visit(page, '/');
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
await window.fuelDB.errors.add({
id: '12345',
error: {
Expand Down Expand Up @@ -109,7 +113,6 @@ test.describe('ReportError', () => {
test('should be able to dismiss all errors', async () => {
await visit(page, '/');
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
await window.fuelDB.errors.add({
id: '12345',
error: {
Expand Down Expand Up @@ -144,7 +147,6 @@ test.describe('ReportError', () => {
test('should hide when the single error is dismissed', async () => {
await visit(page, '/');
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
await window.fuelDB.errors.add({
id: '12345',
error: {
Expand Down Expand Up @@ -176,7 +178,6 @@ test.describe('ReportError', () => {
test('should detect and capture global errors', async () => {
await visit(page, '/');
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
console.error(new Error('Test Error'));
});
await reload(page);
Expand All @@ -191,7 +192,6 @@ test.describe('ReportError', () => {
test('should deduplicate errors', async () => {
await visit(page, '/');
await page.evaluate(async () => {
await window.fuelDB.errors.clear();
await window.fuelDB.errors.add({
id: '12345',
error: {
Expand All @@ -208,7 +208,7 @@ test.describe('ReportError', () => {
},
});
await window.fuelDB.errors.add({
id: '12345',
id: '123456',
error: {
name: 'React error',
message: 'Test Error',
Expand Down
91 changes: 56 additions & 35 deletions packages/app/playwright/mocks/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
encrypt,
} from 'fuels';

import { expect } from '@fuels/playwright-utils';
import { getByAriaLabel } from '../commons/locator';
import { hasText } from '../commons/text';
import { reload, visit } from '../commons/visit';
Expand Down Expand Up @@ -231,42 +232,62 @@ export async function mockData(
accounts.map((account) => account.address)
);

await new Promise((resolve) => setTimeout(resolve, 300));
await expect
.poll(
async () => {
return await page
.evaluate(
async ([accounts, networks, connections, assets, vault, password]: [
Array<WalletAccount>,
Array<NetworkData>,
Array<Connection>,
Array<AssetData>,
SerializedVault,
string,
]) => {
const fuelDB = window.fuelDB;
await fuelDB.errors.clear();
await fuelDB.vaults.clear();
await fuelDB.vaults.add(vault);
await fuelDB.accounts.clear();
await fuelDB.accounts.bulkAdd(accounts);
await fuelDB.networks.clear();
await fuelDB.networks.bulkAdd(networks);
await fuelDB.connections.clear();
await fuelDB.connections.bulkAdd(connections);
const assetsArray = await fuelDB.assets.toArray();
if (assetsArray.length === 0) {
await fuelDB.assets.bulkAdd(assets);
} else {
for (const asset of assets) {
if (
!assetsArray.find(
(a) => JSON.stringify(a) === JSON.stringify(asset)
)
) {
await fuelDB.assets.add(asset);
}
}
}
localStorage.setItem('fuel_isLogged', JSON.stringify(true));
localStorage.setItem('password', password);
},
[
accounts,
networks,
connections,
[ALT_ASSET],
vault,
WALLET_PASSWORD,
]
)
.then(() => true)
.catch(() => false);
},
{ timeout: 15000 }
)
.toBeTruthy();

await page.evaluate(
([accounts, networks, connections, assets, vault, password]: [
Array<WalletAccount>,
Array<NetworkData>,
Array<Connection>,
Array<AssetData>,
SerializedVault,
string,
]) => {
return new Promise((resolve, reject) => {
(async function main() {
try {
const fuelDB = window.fuelDB;
await fuelDB.errors.clear();
await fuelDB.vaults.clear();
await fuelDB.vaults.add(vault);
await fuelDB.accounts.clear();
await fuelDB.accounts.bulkAdd(accounts);
await fuelDB.networks.clear();
await fuelDB.networks.bulkAdd(networks);
await fuelDB.connections.clear();
await fuelDB.connections.bulkAdd(connections);
await fuelDB.assets.bulkAdd(assets);
resolve(await fuelDB.networks.toArray());
} catch (err: unknown) {
reject(err);
}
localStorage.setItem('fuel_isLogged', JSON.stringify(true));
localStorage.setItem('password', password);
})();
});
},
[accounts, networks, connections, [ALT_ASSET], vault, WALLET_PASSWORD]
);
await reload(page);

const accountsWithPkey = accounts.map((acc) => ({
Expand Down
27 changes: 14 additions & 13 deletions packages/app/src/systems/Asset/services/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,20 @@ export class AssetService {

const { decimals, assetId, ...inputRest } = input.data;
const currentNetwork = await NetworkService.getSelectedNetwork();
const newNetworks = currentAsset.networks.map((network) => {
if (
network.type === 'fuel' &&
network.chainId === currentNetwork?.chainId
) {
return {
...network,
assetId,
decimals,
};
}
return network;
});
const newNetworks: (NetworkFuel | NetworkEthereum)[] =
currentAsset.networks.map((network) => {
if (
network.type === 'fuel' &&
network.chainId === currentNetwork?.chainId
) {
return {
...network,
assetId,
decimals,
} as NetworkFuel;
}
return network as NetworkEthereum;
});

const assetToUpdate = {
...currentAsset,
Expand Down
Loading

0 comments on commit 8c9edd3

Please sign in to comment.