Skip to content

Commit

Permalink
Merge pull request #570 from HathorNetwork/release-candidate
Browse files Browse the repository at this point in the history
chore: merge release-candidate into release
  • Loading branch information
r4mmer authored Apr 2, 2024
2 parents afbddb8 + d86bd2b commit d24f959
Show file tree
Hide file tree
Showing 20 changed files with 305 additions and 164 deletions.
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ updates:
directory: /
schedule:
interval: "weekly"
target-branch: "dev"
target-branch: "master"
labels:
- "dependencies"
16 changes: 15 additions & 1 deletion QA.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,21 @@ You can connect your wallet to the testnet (https://node1.foxtrot.testnet.hathor
1. Close and open the wallet again and start a new wallet one without doing backup. It must show a yellow warning saying a backup must be done.
1. Do the backup (following procedures in the 'Initialization' tests). The backup message has to disappear.

1. **Reset menu**
1. Click on the application menu Debug > Reset all data. Then fill the form with "anything" and click on the "Reset all data" button.
1. Check that a message with "Invalid value." appears.
1. Click on "Cancel", the modal should close.
1. Click on the application menu Debug > Reset all data. Then fill the form with "I want to reset my wallet" and click on the "Reset all data" button. The wallet should close.
1. Open the wallet again, it should open the Welcome screen. Do NOT click on "Get started".
1. Close the wallet.

1. **Hardware wallet migration**
1. Uninstall the wallet and install the previous version.
1. Connect your Ledger device to the computer. The Ledger should be initialized already.
1. Start the wallet with the Ledger device and copy the current address.
1. Close the wallet and install the latest version.

1. **Hardware wallet initialization**
1. Reset the wallet one more time.
1. Connect your Ledger device to the computer. The Ledger should be initialized already.
1. Open the Hathor app on Ledger.
1. On the desktop wallet, mark the checkbox and click 'Get Started'.
Expand All @@ -216,6 +229,7 @@ You can connect your wallet to the testnet (https://node1.foxtrot.testnet.hathor
1. Deny the authorization request on Ledger (scroll with left or right and click both buttons on "Reject" step). It should show an error on the wallet.
1. Click 'Try again'. It goes through both steps and asks for authorization again.
1. Grant authorization request (click both buttons on the "Approve" step). It will proceed to 'Loading transactions' screen.
1. Once the wallet is loaded check that the current address match the copied address during "**Hardware wallet migration**"

1. **Ledger wallet screen**
1. On the main wallet screen, confirm 'Address to receive tokens' is truncated (eg: 'HGZmqThwa6...'). There should be a 'Show full address' button next to it.
Expand Down
66 changes: 66 additions & 0 deletions QA_WALLET_SERVICE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
1. **Wallet Service initialization**
1. Start a new wallet
1. Send 1.00 HTR from another wallet to the wallet address.
1. Create a custom token 'WST0', amount 100.
1. Go to Settings and copy the "Unique identifier"
1. Go to the unleash dashboard and add it to the list of UserIDs
1. Close your wallet (not lock) and open it again.
1. Unlock the wallet and check that your history is showing correctly.
1. Check that you have balance for HTR (0.99 HTR) and WST0 (100.00 WST0)
1. Check that you have authorities for mint and melt for WST0.

1. **Wallet screen**
1. Check that you have HTR and other custom tokens on your wallet.
1. Copy the address and send 1.00 HTR from another wallet to this address.
1. Check that we receive a notification for the transaction.
1. Check that the transaction appears in the list, the balance was updated and the address also changed.
1. Click on 'See all addresses' and see the list.
1. Search for the address used to send the transaction and check that it has 'Number of transactions' equal to 1.

1. **Custom tokens**
1. Click on 'Custom tokens', then 'Create a new token'.
1. Create a token 'WS Test Token', 'WTST', amount 100.
1. Validate its symbol appeared selected in the token bar.
1. The list of transactions should have only one, with type 'Token creation' and amount of 100.00.
1. Click on the HTR token (in the token bar) and check if the first transaction is of type 'Token deposit' with amount of 1.00.

1. **Custom token admin**
1. Click on 'WTST' on the token bar and then on 'Administrative tools'
1. Use the 'Melt tokens' to melt all tokens you have.
1. Go to 'Balance & History' and check that the 'Total' is 0 and that the melt transaction appears on the list.
1. Go back to 'Administrative tools' and use 'Mint tokens' mint 100 tokens.
1. Click on 'Balance & History' and check the mint transaction is on the list.
1. Check that the 'Total' and 'Available' are 100.00 WTST
1. Copy the current address and go back to 'Administrative tools'
1. Use the 'Delegate mint' to the address you copied, keep the 'Create another mint output for you?' checked.
1. Check that the message under 'Mint authority management' now reads 'You are the owner of 2 mint outputs'.
1. Use the 'Destroy mint' to destroy one authority.
1. Check that the message under 'Mint authority management' now reads 'You are the owner of 1 mint output'.
1. Use the 'Delegate melt' to the address you copied, keep the 'Create another mint output for you?' checked.
1. Check that the message under 'Melt authority management' now reads 'You are the owner of 2 melt outputs'.
1. Use the 'Destroy melt' to destroy one authority.
1. Check that the message under 'Melt authority management' now reads 'You are the owner of 1 melt output'.

1. **Settings**
1. Go to Settings and click on "Change server"
1. Use the following urls to connect to testnet wallet service.
1. `https://wallet-service.testnet.hathor.network`
1. `wss://ws.wallet-service.testnet.hathor.network`
1. Check that you are connected to the testnet in the upper right corner.
1. Check that your address starts with 'W'.
1. Go to Settings and click on "Change server"
1. Connect to the mainnet wallet service.
1. `https://wallet-service.hathor.network`
1. `wss://ws.wallet-service.hathor.network`
1. Check that you are connected to the mainnet in the upper right corner.
1. Check that your address starts with 'H'.
1. Go to Settings and set "Hide zero-balance tokens" to yes.
1. Go to "WTST" and melt all tokens.
1. Check that "WTST" does not appear on the token bar.
1. Go to Settings and set "Hide zero-balance tokens" to no.
1. Check that "WTST" appears on the token bar.
1. Click on "WTST" and go to "About WS Test Token" and change "Always show this token" to yes.
1. Go to Settings and set "Hide zero-balance tokens" to yes.
1. Melt all WTST tokens.
1. Check that "WTST" is still on the token bar.
1. Check that the "WTST" balance is zero.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"productName": "Hathor Wallet",
"description": "Light wallet for Hathor Network",
"author": "Hathor Labs <[email protected]> (https://hathor.network/)",
"version": "0.27.1-rc5",
"version": "0.28.0-rc1",
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
Expand Down
12 changes: 9 additions & 3 deletions public/electron.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if (process.platform === 'darwin') {
}

const appName = 'Hathor Wallet';
const walletVersion = '0.27.1-rc5';
const walletVersion = '0.28.0-rc1';

const debugMode = (
process.argv.indexOf('--unsafe-mode') >= 0 &&
Expand Down Expand Up @@ -115,14 +115,15 @@ function createWindow () {
{ label: 'Copy', accelerator: 'CmdOrCtrl+C', selector: 'copy:' },
{ label: 'Paste', accelerator: 'CmdOrCtrl+V', selector: 'paste:' },
{ label: 'Select All', accelerator: 'CmdOrCtrl+A', selector: 'selectAll:' }
]}
]},
];

if (debugMode) {
template.push({
label: 'Debug',
submenu: [
{ label: `Open DevTools`, accelerator: 'CmdOrCtrl+B', click: function() { mainWindow.webContents.openDevTools(); }}
{ label: `Open DevTools`, accelerator: 'CmdOrCtrl+B', click: function() { mainWindow.webContents.openDevTools(); }},
{ label: 'Reset all data', click: function() { mainWindow.webContents.send('app:clear_storage'); }},
]
});
};
Expand Down Expand Up @@ -167,6 +168,11 @@ function createWindow () {
}
});

ipcMain.on('app:clear_storage_success', () => {
console.log('Data reset success. Closing window...');
mainWindow.close();
});

addLedgerListeners(mainWindow);
}

Expand Down
15 changes: 15 additions & 0 deletions public/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ Sentry.init({
})

process.once('loaded', () => {
const oldAccessDataRaw = localStorage.getItem('wallet:accessData');
if (oldAccessDataRaw) {
// When migrating from wallets with version v0.26.0 and older initialized with hardware devices
// we need to clean the localStorage since some state left over can cause issues
const accessData = JSON.parse(oldAccessDataRaw);
const isHardware = localStorage.getItem('wallet:type') === 'hardware';
if (accessData.from_xpub || isHardware) {
const uniqueId = localStorage.getItem('app:uniqueId');
localStorage.clear();
localStorage.setItem('localstorage:started', 'true');
localStorage.setItem('app:uniqueId', uniqueId);
}
}


// Set closed in localStorage, so user does not open in the wallet page
localStorage.setItem('localstorage:closed', 'true');

Expand Down
15 changes: 14 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import React, { useEffect, useState } from 'react';
import React, { useEffect, useState, useContext } from 'react';
import { Redirect, Route, Switch, useHistory, useRouteMatch } from 'react-router-dom';
import Wallet from './screens/Wallet';
import SendTokens from './screens/SendTokens';
Expand Down Expand Up @@ -38,6 +38,7 @@ import tokensUtils from './utils/tokens';
import storageUtils from './utils/storage';
import { useDispatch, useSelector } from 'react-redux';
import RequestErrorModal from './components/RequestError';
import { GlobalModalContext, MODAL_TYPES } from './components/GlobalModal';
import createRequestInstance from './api/axiosInstance';
import hathorLib from '@hathor/wallet-lib';
import { IPC_RENDERER } from './constants';
Expand Down Expand Up @@ -67,6 +68,7 @@ function Root() {
});
const dispatch = useDispatch();
const history = useHistory();
const context = useContext(GlobalModalContext);

// Monitors when Ledger device loses connection or the app is closed
useEffect(() => {
Expand Down Expand Up @@ -98,6 +100,17 @@ function Root() {

// If there is an `Inter Process Communication` channel available, initialize Ledger logic
if (IPC_RENDERER) {
// Event called when the user wants to reset all data
IPC_RENDERER.on('app:clear_storage', async () => {
context.showModal(MODAL_TYPES.CONFIRM_CLEAR_STORAGE, {
success: () => {
localStorage.clear();
IPC_RENDERER.send('app:clear_storage_success');
},
});

});

// Registers the event handlers for the ledger

// Event called when user quits hathor app
Expand Down
3 changes: 3 additions & 0 deletions src/components/GlobalModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import ModalLedgerResetTokenSignatures from './ModalLedgerResetTokenSignatures';
import ModalResetAllData from './ModalResetAllData';
import ModalLedgerSignToken from './ModalLedgerSignToken';
import ModalConfirmTestnet from './ModalConfirmTestnet';
import ModalConfirmClearStorage from './ModalConfirmClearStorage';
import ModalSendTx from './ModalSendTx';
import ModalUnregisteredTokenInfo from './ModalUnregisteredTokenInfo';
import ModalPin from "./ModalPin";
Expand All @@ -43,6 +44,7 @@ export const MODAL_TYPES = {
'RESET_ALL_DATA': 'RESET_ALL_DATA',
'LEDGER_SIGN_TOKEN': 'LEDGER_SIGN_TOKEN',
'CONFIRM_TESTNET': 'CONFIRM_TESTNET',
'CONFIRM_CLEAR_STORAGE': 'CONFIRM_CLEAR_STORAGE',
'SEND_TX': 'SEND_TX',
'UNREGISTERED_TOKEN_INFO': 'UNREGISTERED_TOKEN_INFO',
'PIN': 'PIN',
Expand All @@ -63,6 +65,7 @@ export const MODAL_COMPONENTS = {
[MODAL_TYPES.RESET_ALL_DATA]: ModalResetAllData,
[MODAL_TYPES.LEDGER_SIGN_TOKEN]: ModalLedgerSignToken,
[MODAL_TYPES.CONFIRM_TESTNET]: ModalConfirmTestnet,
[MODAL_TYPES.CONFIRM_CLEAR_STORAGE]: ModalConfirmClearStorage,
[MODAL_TYPES.SEND_TX]: ModalSendTx,
[MODAL_TYPES.UNREGISTERED_TOKEN_INFO]: ModalUnregisteredTokenInfo,
[MODAL_TYPES.PIN]: ModalPin,
Expand Down
68 changes: 68 additions & 0 deletions src/components/ModalConfirmClearStorage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useEffect, useState, useCallback } from 'react';
import { t } from 'ttag';
import $ from 'jquery';
import SpanFmt from './SpanFmt';
import { CONFIRM_RESET_MESSAGE } from '../constants';

export default function ModalConfirmClearStorage({ onClose, success }) {
const [confirmText, setConfirmText] = useState('');
const [confirmError, setConfirmError] = useState('');

useEffect(() => {
$('#modalConfirmResetAllData').modal('show');
$('#modalConfirmResetAllData').on('hidden.bs.modal', onClose);

return () => {
$('#modalConfirmResetAllData').modal('hide');
$('#modalConfirmResetAllData').off();
};
}, []);

const confirmResetData = useCallback(() => {
if (confirmText.toLowerCase() !== CONFIRM_RESET_MESSAGE.toLowerCase()) {
setConfirmError(t`Invalid value.`);
return;
}

success();
}, [confirmText, setConfirmError]);

return (
<div className="modal fade" id="modalConfirmResetAllData" tabIndex="-1" role="dialog" aria-labelledby="alertModal" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div className="modal-dialog" role="document">
<div className="modal-content">
<div className="modal-header">
<h5 className="modal-title">
{ t`Confirm reset all data` }
</h5>
</div>
<div className="modal-body">
<div>
<p><SpanFmt>{t`**Make sure you have the backup of your seed because this will turn your wallet into a fresh install.**`}</SpanFmt></p>
<p>{t`Do you want to reset all of your wallet data? Only continue if you know what you are doing.`}</p>
<p>{t`This action cannot be undone. All your data will be erased.`}</p>
<p>{t`Your wallet uniqueId will be reset.`}</p>
<p>uniqueId: {localStorage.getItem('app:uniqueId')}</p>
<p>{t`If you want to reset all data, please type '${CONFIRM_RESET_MESSAGE}' in the box below and click on 'Reset all data' button.`}</p>
<p>{t`After resetting the data, the application will close, and you will need to open it again.`}</p>
<div>
<input type="text" className="form-control" placeholder={t`Write '${CONFIRM_RESET_MESSAGE}'`} onChange={(e) => setConfirmText(e.target.value)} />
<span className="text-danger ml-2">
{confirmError}
</span>
</div>
</div>
</div>
<div className="modal-footer">
<button onClick={confirmResetData} type="button" className="btn btn-secondary">
{t`Reset all data`}
</button>
<button onClick={onClose} type="button" className="btn btn-hathor">
{ t`Cancel` }
</button>
</div>
</div>
</div>
</div>
);
}
12 changes: 7 additions & 5 deletions src/components/RequestError.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ import { t } from 'ttag';
import $ from 'jquery';
import createRequestInstance from '../api/axiosInstance';
import SpanFmt from './SpanFmt';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import hathorLib from '@hathor/wallet-lib';
import wallet from '../utils/wallet';
import { useHistory } from 'react-router-dom';

/**
Expand All @@ -28,8 +27,11 @@ const MODAL_DOM_ID = '#requestErrorModal';
*/
function RequestErrorModal() {
const history = useHistory();
const lastFailedRequest = useSelector(state => state.lastFailedRequest);
const requestErrorStatusCode = useSelector(state => state.requestErrorStatusCode);
const dispatch = useDispatch();
const { lastFailedRequest, requestErrorStatusCode } = useSelector(state => ({
lastFailedRequest: state.lastFailedRequest,
requestErrorStatusCode: state.requestErrorStatusCode,
}));

const advancedDataRef = useRef();
const showAdvancedLinkRef = useRef();
Expand Down Expand Up @@ -75,7 +77,7 @@ function RequestErrorModal() {
// it's paginated with async/await and does not use promise resolve/reject like the others
// We already have an issue on the lib to track this (https://github.com/HathorNetwork/hathor-wallet-lib/issues/59)
// So we handle here this retry manually with a reload (like the one when the connection is lost)
wallet.reloadData();
dispatch({ type: 'WALLET_RELOADING' });
} else {
const config = lastFailedRequest;
const axios = createRequestInstance(config.resolve);
Expand Down
2 changes: 1 addition & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const WALLET_HISTORY_COUNT = 10;
/**
* Wallet version
*/
export const VERSION = '0.27.1-rc5';
export const VERSION = '0.28.0-rc1';

/**
* Before this version the data in localStorage from the wallet is not compatible
Expand Down
1 change: 1 addition & 0 deletions src/sagas/featureToggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ export function* setupUnleashListeners(unleashClient) {
}

function mapFeatureToggles(toggles) {
console.log('feature toggles', toggles);
return toggles.reduce((acc, toggle) => {
acc[toggle.name] = get(
toggle,
Expand Down
Loading

0 comments on commit d24f959

Please sign in to comment.