Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd2a1ef825 |
@@ -1488,8 +1488,10 @@ view would leave a wallet one click from deletion.
|
|||||||
- **Transitions**:
|
- **Transitions**:
|
||||||
- "Import" with a valid entry and a matching password of at least 12
|
- "Import" with a valid entry and a matching password of at least 12
|
||||||
characters → creates the wallet, clears the navigation stack, and →
|
characters → creates the wallet, clears the navigation stack, and →
|
||||||
**Home**. The phrase and xprv modes then scan for further used addresses
|
**Home**. When no address is active yet, as on the first wallet, the new
|
||||||
and report the count as a flash message.
|
wallet's first address becomes the active one. The phrase and xprv modes
|
||||||
|
then scan for further used addresses and report the count as a flash
|
||||||
|
message.
|
||||||
- "Import" with a missing, short or mismatched password → full-sentence
|
- "Import" with a missing, short or mismatched password → full-sentence
|
||||||
error on the error line, no screen change
|
error on the error line, no screen change
|
||||||
- "Import" with an invalid entry or a duplicate wallet or address → flash
|
- "Import" with an invalid entry or a duplicate wallet or address → flash
|
||||||
|
|||||||
@@ -194,6 +194,9 @@ async function importMnemonic(ctx) {
|
|||||||
};
|
};
|
||||||
state.wallets.push(wallet);
|
state.wallets.push(wallet);
|
||||||
state.hasWallet = true;
|
state.hasWallet = true;
|
||||||
|
if (state.activeAddress === null) {
|
||||||
|
state.activeAddress = firstAddress;
|
||||||
|
}
|
||||||
await saveState();
|
await saveState();
|
||||||
clearViewStack();
|
clearViewStack();
|
||||||
ctx.renderWalletList();
|
ctx.renderWalletList();
|
||||||
@@ -254,6 +257,9 @@ async function importPrivateKey(ctx) {
|
|||||||
addresses: [{ address: addr, balance: "0.0000", tokenBalances: [] }],
|
addresses: [{ address: addr, balance: "0.0000", tokenBalances: [] }],
|
||||||
});
|
});
|
||||||
state.hasWallet = true;
|
state.hasWallet = true;
|
||||||
|
if (state.activeAddress === null) {
|
||||||
|
state.activeAddress = addr;
|
||||||
|
}
|
||||||
await saveState();
|
await saveState();
|
||||||
clearViewStack();
|
clearViewStack();
|
||||||
ctx.renderWalletList();
|
ctx.renderWalletList();
|
||||||
@@ -315,6 +321,9 @@ async function importXprvKey(ctx) {
|
|||||||
};
|
};
|
||||||
state.wallets.push(wallet);
|
state.wallets.push(wallet);
|
||||||
state.hasWallet = true;
|
state.hasWallet = true;
|
||||||
|
if (state.activeAddress === null) {
|
||||||
|
state.activeAddress = firstAddress;
|
||||||
|
}
|
||||||
await saveState();
|
await saveState();
|
||||||
clearViewStack();
|
clearViewStack();
|
||||||
ctx.renderWalletList();
|
ctx.renderWalletList();
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// Adding the first wallet left no address active until the popup was reopened,
|
||||||
|
// so Send and Receive on Home only said "No active address selected."
|
||||||
|
// (https://git.eeqj.de/sneak/AutistMask/issues/512). Each test boots a fresh
|
||||||
|
// install, adds the first wallet through one of the three import tabs, and
|
||||||
|
// opens Receive from Home in the same popup.
|
||||||
|
|
||||||
|
const { HDNodeWallet, Mnemonic, Wallet } = require("ethers");
|
||||||
|
|
||||||
|
const { bootPopup, cleanupPopup } = require("./support/popupBoot");
|
||||||
|
|
||||||
|
const PHRASE =
|
||||||
|
"abandon abandon abandon abandon abandon abandon " +
|
||||||
|
"abandon abandon abandon abandon abandon about";
|
||||||
|
const PRIVATE_KEY = "0x" + "11".repeat(32);
|
||||||
|
// The master key of PHRASE, so its first address is the phrase's.
|
||||||
|
const XPRV = HDNodeWallet.fromSeed(
|
||||||
|
Mnemonic.fromPhrase(PHRASE).computeSeed(),
|
||||||
|
).extendedKey;
|
||||||
|
const PASSWORD = "correct horse battery staple";
|
||||||
|
|
||||||
|
const PHRASE_ADDRESS = HDNodeWallet.fromPhrase(PHRASE).address;
|
||||||
|
|
||||||
|
const TABS = [
|
||||||
|
{
|
||||||
|
tab: "tab-mnemonic",
|
||||||
|
field: "wallet-mnemonic",
|
||||||
|
secret: PHRASE,
|
||||||
|
address: PHRASE_ADDRESS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tab: "tab-privkey",
|
||||||
|
field: "import-private-key",
|
||||||
|
secret: PRIVATE_KEY,
|
||||||
|
address: new Wallet(PRIVATE_KEY).address,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tab: "tab-xprv",
|
||||||
|
field: "import-xprv-key",
|
||||||
|
secret: XPRV,
|
||||||
|
address: PHRASE_ADDRESS,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
cleanupPopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("the first wallet's first address is active right away", () => {
|
||||||
|
test.each(TABS)(
|
||||||
|
"added from $tab, Receive opens on it",
|
||||||
|
async ({ tab, field, secret, address }) => {
|
||||||
|
const page = await bootPopup(undefined);
|
||||||
|
expect(page.pageErrors).toEqual([]);
|
||||||
|
await page.click("btn-welcome-add");
|
||||||
|
await page.click(tab);
|
||||||
|
page.node(field).value = secret;
|
||||||
|
page.node("add-wallet-password").value = PASSWORD;
|
||||||
|
page.node("add-wallet-password-confirm").value = PASSWORD;
|
||||||
|
await page.click("btn-add-wallet-confirm");
|
||||||
|
expect(page.visibleViews()).toEqual(["main"]);
|
||||||
|
|
||||||
|
await page.click("btn-main-receive");
|
||||||
|
expect(page.visibleViews()).toEqual(["receive"]);
|
||||||
|
expect(page.node("receive-address-block").dataset.full).toBe(
|
||||||
|
address,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -258,12 +258,17 @@ async function bootPopup(stored, options) {
|
|||||||
formatAddressTotal: () => "",
|
formatAddressTotal: () => "",
|
||||||
getAddressValue: () => ({ usd: null, partial: false }),
|
getAddressValue: () => ({ usd: null, partial: false }),
|
||||||
}));
|
}));
|
||||||
|
// scanForAddresses() answers in the real one's shape, a scan that found
|
||||||
|
// no used address: AddWallet reads `addresses` from it.
|
||||||
jest.doMock("../../src/shared/balances", () => ({
|
jest.doMock("../../src/shared/balances", () => ({
|
||||||
fetchTokenBalances: jest.fn(async () => []),
|
fetchTokenBalances: jest.fn(async () => []),
|
||||||
refreshBalances: jest.fn(async () => {}),
|
refreshBalances: jest.fn(async () => {}),
|
||||||
lookupTokenInfo: jest.fn(async () => null),
|
lookupTokenInfo: jest.fn(async () => null),
|
||||||
getProvider: () => ({}),
|
getProvider: () => ({}),
|
||||||
scanForAddresses: jest.fn(async () => []),
|
scanForAddresses: jest.fn(async () => ({
|
||||||
|
addresses: [],
|
||||||
|
nextIndex: 1,
|
||||||
|
})),
|
||||||
}));
|
}));
|
||||||
// filterTransactions() answers in the real one's shape: Home,
|
// filterTransactions() answers in the real one's shape: Home,
|
||||||
// AddressDetail and AddressToken read both fields, and a bare list makes
|
// AddressDetail and AddressToken read both fields, and a bare list makes
|
||||||
|
|||||||
Reference in New Issue
Block a user