Compare commits
1
Commits
next
...
ff364edd88
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff364edd88 |
@@ -2395,6 +2395,8 @@ view would leave a wallet one click from deletion.
|
|||||||
- Raw data: full calldata displayed inline (shown if present)
|
- Raw data: full calldata displayed inline (shown if present)
|
||||||
- Password input and an error line
|
- Password input and an error line
|
||||||
- "Confirm" / "Reject" buttons
|
- "Confirm" / "Reject" buttons
|
||||||
|
- **Behavior**: Every etherscan link on the screen opens the explorer of the
|
||||||
|
network the transaction was populated on, whichever network is active.
|
||||||
- **Transitions**:
|
- **Transitions**:
|
||||||
- "Confirm" (correct password) → decrypts and signs the transaction it was
|
- "Confirm" (correct password) → decrypts and signs the transaction it was
|
||||||
shown, exactly as shown, hands the signed transaction to the background to
|
shown, exactly as shown, hands the signed transaction to the background to
|
||||||
|
|||||||
@@ -58,9 +58,15 @@ const { notify, runtimeApi, sendMessage } = require("../../shared/browserApi");
|
|||||||
|
|
||||||
const erc20Iface = new Interface(ERC20_ABI);
|
const erc20Iface = new Interface(ERC20_ABI);
|
||||||
|
|
||||||
function approvalAddressHtml(address) {
|
// The link opens the explorer of the network with `chainId`, or of the active
|
||||||
|
// network when none is given. A chain id that names no network has no
|
||||||
|
// explorer, so the address is drawn without a link.
|
||||||
|
function approvalAddressHtml(address, chainId) {
|
||||||
const title = addressTitle(address, state.wallets);
|
const title = addressTitle(address, state.wallets);
|
||||||
return renderAddressHtml(address, { title });
|
if (chainId && !networkByChainId(chainId)) {
|
||||||
|
return renderAddressHtml(address, { title, noLink: true });
|
||||||
|
}
|
||||||
|
return renderAddressHtml(address, { title, chainId });
|
||||||
}
|
}
|
||||||
|
|
||||||
// The amount line for a decoded ERC-20 call. With a known scale it is the
|
// The amount line for a decoded ERC-20 call. With a known scale it is the
|
||||||
@@ -338,8 +344,14 @@ function showTxApproval(details) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Every address link on this screen opens the explorer of the network the
|
||||||
|
// transaction is for, which the Network line names, whichever network is
|
||||||
|
// active.
|
||||||
$("approve-tx-origin").textContent = details.origin;
|
$("approve-tx-origin").textContent = details.origin;
|
||||||
$("approve-tx-from").innerHTML = approvalAddressHtml(details.approvedFrom);
|
$("approve-tx-from").innerHTML = approvalAddressHtml(
|
||||||
|
details.approvedFrom,
|
||||||
|
approvedTx.chainId,
|
||||||
|
);
|
||||||
|
|
||||||
// Show token symbol next to contract address if known on the network the
|
// Show token symbol next to contract address if known on the network the
|
||||||
// transaction is for
|
// transaction is for
|
||||||
@@ -349,7 +361,7 @@ function showTxApproval(details) {
|
|||||||
if (symbol) {
|
if (symbol) {
|
||||||
toHtml += `<div class="font-bold mb-1">${escapeHtml(symbol)}</div>`;
|
toHtml += `<div class="font-bold mb-1">${escapeHtml(symbol)}</div>`;
|
||||||
}
|
}
|
||||||
toHtml += approvalAddressHtml(toAddr);
|
toHtml += approvalAddressHtml(toAddr, approvedTx.chainId);
|
||||||
$("approve-tx-to").innerHTML = toHtml;
|
$("approve-tx-to").innerHTML = toHtml;
|
||||||
} else {
|
} else {
|
||||||
$("approve-tx-to").innerHTML = escapeHtml(CONTRACT_CREATION_TEXT);
|
$("approve-tx-to").innerHTML = escapeHtml(CONTRACT_CREATION_TEXT);
|
||||||
@@ -388,7 +400,10 @@ function showTxApproval(details) {
|
|||||||
if (d.isToken) {
|
if (d.isToken) {
|
||||||
detailsHtml += `<div class="font-bold">${escapeHtml(tokenLabel(d.address, approvedTx.chainId) || "Unknown token")}</div>`;
|
detailsHtml += `<div class="font-bold">${escapeHtml(tokenLabel(d.address, approvedTx.chainId) || "Unknown token")}</div>`;
|
||||||
}
|
}
|
||||||
detailsHtml += approvalAddressHtml(d.address);
|
detailsHtml += approvalAddressHtml(
|
||||||
|
d.address,
|
||||||
|
approvedTx.chainId,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
detailsHtml += `<div class="font-bold">${escapeHtml(d.value)}</div>`;
|
detailsHtml += `<div class="font-bold">${escapeHtml(d.value)}</div>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
// The approval screen for a site's Sepolia token transfer while Ethereum
|
// The approval screen for a site's Sepolia token transfer while Ethereum
|
||||||
// Mainnet is active (https://git.eeqj.de/sneak/AutistMask/issues/629).
|
// Mainnet is active.
|
||||||
//
|
//
|
||||||
// The screen named the token, and scaled its amount, from the active network's
|
// The screen named the token, and scaled its amount, from the active network's
|
||||||
// tracked tokens and balances, so a token the wallet tracks on Sepolia read as
|
// tracked tokens and balances, so a token the wallet tracks on Sepolia read as
|
||||||
// an unknown token with its amount in base units, and the screens after it
|
// an unknown token with its amount in base units, and the screens after it
|
||||||
// labelled the amount `?`. It now uses what the wallet knows of the tokens on
|
// labelled the amount `?` (https://git.eeqj.de/sneak/AutistMask/issues/629).
|
||||||
// the network the transaction is for.
|
// It now uses what the wallet knows of the tokens on the network the
|
||||||
|
// transaction is for.
|
||||||
|
//
|
||||||
|
// Its address links opened the active network's explorer
|
||||||
|
// (https://git.eeqj.de/sneak/AutistMask/issues/631). They now open the
|
||||||
|
// explorer of the network the transaction is for.
|
||||||
//
|
//
|
||||||
// Driven through the real approval screen, password and Confirm included,
|
// Driven through the real approval screen, password and Confirm included,
|
||||||
// against a minimal DOM stub in the shape tests/swapStatusAmount.test.js uses.
|
// against a minimal DOM stub in the shape tests/swapStatusAmount.test.js uses.
|
||||||
@@ -107,10 +112,13 @@ function decodedLine(label) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open the approval screen, with Ethereum Mainnet active and FROM holding
|
// Open the approval screen, with Ethereum Mainnet active and FROM holding
|
||||||
// `tokenBalances` there, for the site's Sepolia transaction sending
|
// `tokenBalances` there, for the site's transaction sending TRANSFER_DATA to
|
||||||
// TRANSFER_DATA to the token. Confirm answers the signed transaction with a
|
// the token, on Sepolia unless `chainId` names another chain. Confirm answers
|
||||||
// failure, which leads to the error screen.
|
// the signed transaction with a failure, which leads to the error screen.
|
||||||
async function showSepoliaTransfer(tokenBalances = []) {
|
async function showSepoliaTransfer(
|
||||||
|
tokenBalances = [],
|
||||||
|
chainId = NETWORKS.sepolia.chainId,
|
||||||
|
) {
|
||||||
globalThis.document = makeDocument();
|
globalThis.document = makeDocument();
|
||||||
globalThis.window = { location: { search: "" }, close: () => {} };
|
globalThis.window = { location: { search: "" }, close: () => {} };
|
||||||
globalThis.chrome.runtime = {
|
globalThis.chrome.runtime = {
|
||||||
@@ -131,7 +139,7 @@ async function showSepoliaTransfer(tokenBalances = []) {
|
|||||||
approvedTx: {
|
approvedTx: {
|
||||||
type: 2,
|
type: 2,
|
||||||
from: FROM,
|
from: FROM,
|
||||||
chainId: NETWORKS.sepolia.chainId,
|
chainId,
|
||||||
nonce: "0x7",
|
nonce: "0x7",
|
||||||
gasLimit: "0x30d40",
|
gasLimit: "0x30d40",
|
||||||
maxPriorityFeePerGas: "0x3b9aca00",
|
maxPriorityFeePerGas: "0x3b9aca00",
|
||||||
@@ -218,3 +226,45 @@ test("a token tracked and held on mainnet only is not named, and its amount is i
|
|||||||
'<div class="font-bold">1234500000 base units (decimals unknown)</div>',
|
'<div class="font-bold">1234500000 base units (decimals unknown)</div>',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The From and Contract lines, and the decoded Token and Recipient lines.
|
||||||
|
test("every address links to the Sepolia explorer", async () => {
|
||||||
|
await showSepoliaTransfer();
|
||||||
|
const sepolia = NETWORKS.sepolia.explorerUrl;
|
||||||
|
expect(node("approve-tx-from").innerHTML).toContain(
|
||||||
|
`href="${sepolia}/address/${FROM}"`,
|
||||||
|
);
|
||||||
|
expect(node("approve-tx-to").innerHTML).toContain(
|
||||||
|
`href="${sepolia}/address/${TOKEN}"`,
|
||||||
|
);
|
||||||
|
expect(decodedLine("Token")).toContain(
|
||||||
|
`href="${sepolia}/address/${TOKEN}"`,
|
||||||
|
);
|
||||||
|
expect(decodedLine("Recipient")).toContain(
|
||||||
|
`href="${sepolia}/address/${RECIPIENT}"`,
|
||||||
|
);
|
||||||
|
for (const id of [
|
||||||
|
"approve-tx-from",
|
||||||
|
"approve-tx-to",
|
||||||
|
"approve-tx-decoded-details",
|
||||||
|
]) {
|
||||||
|
expect(node(id).innerHTML).not.toContain(NETWORKS.mainnet.explorerUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Chain id 1337 names no network here, so it has no explorer to link to.
|
||||||
|
test("a transaction on a chain id that names no network is shown with no address links", async () => {
|
||||||
|
await showSepoliaTransfer([], "0x539");
|
||||||
|
expect(state.currentView).toBe("approve-tx");
|
||||||
|
expect(node("approve-tx-network").textContent).toBe(
|
||||||
|
"Unknown network (chain id 1337)",
|
||||||
|
);
|
||||||
|
expect(node("approve-tx-from").innerHTML).toContain(FROM);
|
||||||
|
for (const id of [
|
||||||
|
"approve-tx-from",
|
||||||
|
"approve-tx-to",
|
||||||
|
"approve-tx-decoded-details",
|
||||||
|
]) {
|
||||||
|
expect(node(id).innerHTML).not.toContain("href=");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -475,7 +475,7 @@ describe("every way to a signature or the private key refuses a defective wallet
|
|||||||
to: RECIPIENT,
|
to: RECIPIENT,
|
||||||
value: "0x0",
|
value: "0x0",
|
||||||
data: "0x",
|
data: "0x",
|
||||||
chainId: 1,
|
chainId: "0x1",
|
||||||
nonce: 0,
|
nonce: 0,
|
||||||
gasLimit: "21000",
|
gasLimit: "21000",
|
||||||
maxFeePerGas: "1000000000",
|
maxFeePerGas: "1000000000",
|
||||||
|
|||||||
Reference in New Issue
Block a user